YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
- π CampusMind AI
- π Table of Contents
- π― The Problem This Solves
- β¨ Features
- π§ The AI Feature
- π§° Tech Stack and AI Models
- πΈ Screenshots
- π Project Structure
- π Requirements
- π Setup and How to Run
- π₯ Persistent Memory with Firestore (Optional)
- βοΈ Deploying to Streamlit Community Cloud
- π§ Using the App
- β οΈ Notes on Persistence
- π©Ί Troubleshooting
- πΊοΈ Roadmap and Future Work
- π€ Author
- π Table of Contents
π CampusMind AI
A multi-persona AI study companion for university students β built with Streamlit and the Groq API.
π Live App
https://campusmind-ai-aazankhann.streamlit.app
No account or login is needed β visiting the app assigns a random session ID as a ?uid= query parameter in the URL (get_or_create_session_id() in app.py). Bookmark the URL with your uid in it to come back to the same memory and chat history later.
π‘ Tip: If your system uses Light Mode by default, click the Light Mode button in the left sidebar to match the app's theme.
π Table of Contents
- The Problem This Solves
- Features
- The AI Feature
- Tech Stack and AI Models
- Screenshots
- Project Structure
- Requirements
- Setup and How to Run
- Persistent Memory with Firestore (Optional)
- Deploying to Streamlit Community Cloud
- Using the App
- Notes on Persistence
- Troubleshooting
- Roadmap and Future Work
- Author
π― The Problem This Solves
University students juggle several different jobs in a single semester β write code for an assignment, get feedback on an essay, plan revision around three overlapping exam dates, dig through a 40-page lecture PDF for one definition, and figure out where to even start a research paper. In practice that means bouncing between a general chatbot, a separate PDF summarizer, a to-do app, and whatever else is open in another tab β re-explaining who you are and what course you're in every single time.
CampusMind AI consolidates that into one assistant with five purpose-built personas (Campus Assistant, Python Tutor, Writing Coach, Study Planner, Research Helper), each with its own behavior, plus a memory layer that quietly remembers your name, major, year, and university so you're not repeating yourself in every new chat.
Who it's for: university students β the primary use case is CS/STEM students at institutions like IIUI who want coding help, writing feedback, and PDF-based Q&A on lecture material in one place, but the personas generalize to any student juggling coursework across subjects.
β¨ Features
Conversation
- Fast, multi-turn chat powered by Groq-hosted LLMs, with conversation history automatically trimmed to stay within context limits.
- Model picker β swap between
openai/gpt-oss-120b(best overall),openai/gpt-oss-20b(fastest), andqwen/qwen3.6-27b(best for coding & reasoning) on the fly, mid-conversation.
Personas
- Five switchable personas β Campus Assistant, Python Tutor, Writing Coach, Study Planner, and Research Helper β each with its own system prompt.
- Personas are scoped per browser session, so they never leak between different users.
- Switching personas gives a visible confirmation (the active one highlights in orange, plus a toast).
Memory
- Auto-detects and remembers your name, major, year, and university from what you type β no form to fill in.
- Remembered facts are injected into every future response so the assistant stays "in character" as your assistant, not a stranger's.
- Memory is viewable and clearable anytime from the sidebar.
Document Q&A
- Upload a PDF and ask questions about its contents directly in chat.
- Built-in privacy rule stops the model from surfacing names, emails, or contact details found inside the uploaded file, even if asked directly.
Utility
- Chat export β download the full conversation as JSON.
- Custom dark UI β Syne/DM Mono typography, animated collapsible sidebar, auto-scrolling chat.
- Optional Firestore-backed persistence so memory and history survive redeploys (falls back gracefully to session/local-file storage if not configured).
π§ The AI Feature
The core AI feature is the persona-driven conversational engine: a Groq-hosted LLM whose system prompt is assembled fresh on every turn from three layers β the active persona, remembered facts about the student, and (optionally) uploaded document context. All quotes below are the literal strings from chatbot.py / app.py.
1. Base system prompt (Campus Assistant / default persona)
Defined once as BASE_SYSTEM_PROMPT in chatbot.py and reused as the default persona:
You are CampusMind AI, a friendly and knowledgeable campus assistant.
You help students with academic questions, study tips, campus life, and general knowledge.
You are warm, encouraging, and clear in your explanations.
Always remember and use personal details the user shares (name, major, interests, university).
Keep responses concise unless the user asks for more detail.
CODE FORMATTING RULES β follow these strictly every time you write code:
- ALWAYS wrap code in markdown fenced code blocks with the correct language tag.
Examples: ```python ... ``` or ```cpp ... ``` or ```java ... ``` or ```javascript ... ```
- ALWAYS write complete, fully working code β never truncate, never use placeholders like # ... or // rest of code here.
- ALWAYS include every import, every function, and every line needed to run the code as-is.
- For multiple snippets in one response, use a separate fenced block for each one.
- Add a brief inline comment above complex lines to explain what they do.
- If the code is long, still write it in full β never shorten or summarise it.
2. Persona system prompts
Each persona button in the sidebar swaps in its own short system prompt (the PERSONAS dict in app.py), replacing the base prompt for that session:
| Persona | System prompt |
|---|---|
| π Python Tutor | You are CampusMind AI acting as a Python tutor. Only answer coding questions. Give short code examples. |
| βοΈ Writing Coach | You are CampusMind AI acting as a writing coach. Help with clarity, grammar, and style. |
| π Study Planner | You are CampusMind AI acting as a study planner. Help with schedules, time management, and exam prep. |
| π Research Helper | You are CampusMind AI acting as a research assistant. Help find sources, summarize topics, and structure essays. |
Persona choice lives on the Chatbot instance inside st.session_state β deliberately not a module-level global β so one student's active persona can never leak into another user's session on the same server process.
3. Rule-based memory (not an LLM call)
Memory extraction is intentionally not an AI step β it's a fast, deterministic pass with re.search() over each message (Memory.update_from_message() in chatbot.py), looking for patterns like:
- Name:
(?:my name is|i'm|i am|call me)\s+([A-Z][a-z]+(?: [A-Z][a-z]+)?) - Major:
(?:studying|majoring in|i study|my major is|my field is)\s+([a-zA-Z &]+?)(?:\.|,|\n|$) - Year:
freshman|sophomore|junior|senior|1st year|2nd year|... - University:
(?:at|attend|go to|from|study at)\s+([A-Z][a-zA-Z ]+?(?:University|College|Institute|School|Academy))
Whatever is captured is saved to Memory.facts and rendered into a plain-text block (to_prompt_block()) that's prepended to the system prompt on every future turn β e.g. "Known facts about this user: - Name: Aazan - University: IIUI" β so the LLM stays personalized without a real extraction model in the loop.
4. Privacy-aware PDF grounding
When a PDF is uploaded, pdfplumber extracts its text and Chatbot._system_prompt() appends the first 6,000 characters as context, wrapped in this literal instruction block:
The user uploaded a document. Use it to answer questions about its academic content only.
IMPORTANT PRIVACY RULES for this document:
- NEVER mention, reveal, or repeat any person's name found in the document (teachers, professors, authors, instructors, students, or anyone else).
- NEVER reveal emails, phone numbers, office hours, room numbers, or any personal contact details.
- NEVER refer to who wrote or created the document.
- Focus ONLY on the academic subject matter, concepts, topics, and educational content.
--- DOCUMENT ---
{document text, truncated to 6000 characters}
--- END ---
π§° Tech Stack and AI Models
| Layer | Tool / Service | Purpose |
|---|---|---|
| UI / frontend | Streamlit | Chat interface, sidebar controls, session state |
| LLM inference | Groq API | Ultra-fast hosted inference for chat and persona behavior |
| AI models | openai/gpt-oss-120b, openai/gpt-oss-20b, qwen/qwen3.6-27b |
highest-quality responses and reasoning / fast, responsive chat / lexcellent for programming and technical questions |
| Fact extraction | Python re (regex) |
Rule-based, non-AI extraction of name/major/year/university from user messages |
| PDF parsing | pdfplumber | Extracts text from uploaded PDFs for document Q&A |
| Persistent storage | Firebase Firestore + firebase-admin |
Optional cross-session persistence for memory and chat history |
| Language | Python 3.9+ | Core application logic |
| Hosting | Streamlit Community Cloud | Deployment of the live app |
| Version control | Git / GitHub | Source control and deployment source |
πΈ Screenshots
Main chat view β the empty-state screen with the randomized greeting and message input.
Memory + persona recall in action β the sidebar shows the live session ID, model picker, PDF uploader, and remembered facts (Name: Aazan Khan), while the chat itself shows the model recalling that name mid-conversation.
PDF-grounded Q&A β a lecture PDF (PF Lecture 18 static and Automatic Variables.pdf) is loaded, and the assistant answers a question about it directly from the document, including reproducing the relevant C++ function.
π Project Structure
campusmind-ai/
βββ app.py # Streamlit interface
βββ chatbot.py # Core chatbot logic (Groq client, memory, personas, PDF context)
βββ firestore_store.py # Firestore persistence layer (memory + chat history)
βββ requirements.txt # Python dependencies
βββ .streamlit/
β βββ secrets.toml # Local secrets template (not committed)
βββ README.md
π Requirements
- Python 3.9+
- A Groq API key (free tier available)
requirements.txt:
streamlit>=1.35
groq>=0.9
pdfplumber>=0.11
gTTS>=2.5
firebase-admin>=6.5
π Setup and How to Run
1. Clone and enter the project
git clone https://github.com/<your-username>/campusmind-ai.git
cd campusmind-ai
2. Create a virtual environment and install dependencies
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
3. Set your Groq API key
Locally, export it as an environment variable:
export GROQ_API_KEY=gsk_your_key_here # Windows: set GROQ_API_KEY=gsk_your_key_here
Or create .streamlit/secrets.toml:
GROQ_API_KEY = "gsk_your_key_here"
4. Run the app
streamlit run app.py
The app opens at http://localhost:8501.
π₯ Persistent Memory with Firestore (Optional)
By default, memory and chat history reset whenever the app restarts (see Notes on Persistence). To make them survive redeploys, connect a Firebase Firestore database.
1. Create a Firebase project Go to console.firebase.google.com β Add project. Then enable Firestore Database (Build β Firestore Database β Create database, start in production mode).
2. Create a service account key Project settings β Service accounts β Generate new private key. This downloads a JSON file β keep it secret, never commit it.
3. Add it to Streamlit secrets
Open the downloaded JSON and copy its fields into .streamlit/secrets.toml (locally) or the Secrets panel (Streamlit Cloud) under a [firebase] table:
GROQ_API_KEY = "gsk_your_key_here"
[firebase]
type = "service_account"
project_id = "your-project-id"
private_key_id = "..."
private_key = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
client_email = "firebase-adminsdk-...@your-project-id.iam.gserviceaccount.com"
client_id = "..."
auth_uri = "https://accounts.google.com/o/oauth2/auth"
token_uri = "https://oauth2.googleapis.com/token"
auth_provider_x509_cert_url = "https://www.googleapis.com/oauth2/v1/certs"
client_x509_cert_url = "..."
universe_domain = "googleapis.com"
The
private_keymust keep its\nline breaks exactly as in the downloaded JSON β TOML needs them written as literal\ninside the quoted string, not real newlines.
4. Install the dependency and run
pip install firebase-admin
streamlit run app.py
How it works: there's no login system. Instead, each visit gets a random session ID appended to the URL (?uid=...) the first time the app loads. That ID is the Firestore document key for that person's memory + chat history. Bookmark or save the URL with the uid in it to return to the same data later β a fresh URL means fresh (empty) memory. The sidebar's π Session section shows the current ID and confirms whether Firestore is actually connected (it falls back to session-only memory automatically if secrets aren't configured, so the app still runs without Firebase set up).
If you'd rather have real accounts instead of a bookmarkable link (so memory follows a person across devices without needing the URL), the next step up is adding Firebase Authentication β see Roadmap.
βοΈ Deploying to Streamlit Community Cloud
- Push this repo to GitHub.
- Go to share.streamlit.io and create a new app pointing at
app.py. - In App settings β Secrets, add:
(and theGROQ_API_KEY = "gsk_your_key_here"[firebase]block too, if you're using persistent memory) - Deploy. The app reads secrets from
st.secretsautomatically β no code changes needed. - This project is already live at the URL in Live App above β if you redeploy under a new app name, update that link.
π§ Using the App
| Action | How |
|---|---|
| Chat | Type in the input box at the bottom and press Enter. |
| Switch persona | Click any persona button in the sidebar β the active one highlights in orange, and a confirmation toast appears. |
| Upload a PDF | Use the sidebar file uploader; a banner confirms it's loaded, and you can immediately ask questions about it. |
| Change model | Pick from the sidebar dropdown β quality vs. speed tradeoff. |
| View/clear memory | Remembered facts show in the sidebar; clear them with ποΈ Clear Memory. |
| Clear chat | π Clear Chat resets the conversation (keeps memory). |
| Export chat | πΎ Export downloads the conversation as JSON. |
β οΈ Notes on Persistence
- Conversation history lives in
st.session_stateβ it resets when the browser tab is refreshed or the session ends. - Memory (name, major, etc.) and chat history are written to Firestore when
[firebase]secrets are configured (see Persistent Memory with Firestore) β this survives redeploys and restarts, keyed to theuidin the page URL. Without Firestore configured, memory falls back to a local JSON file (campusmind_memory.json) that survives a refresh but resets on redeploys, since Streamlit Community Cloud's filesystem is ephemeral. - Personas are stored on the
Chatbotinstance insidest.session_state, so they're isolated per user session and won't leak between visitors.
π©Ί Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| "API key not set" error | GROQ_API_KEY missing |
Set it via environment variable (local) or st.secrets (cloud). |
β οΈ Rate limit reached |
Too many requests in a short window | Wait a few seconds; consider switching to openai/gpt-oss-120b. |
| PDF upload fails / empty context | Scanned/image-only PDF with no extractable text | Use a text-based PDF, or OCR it first. |
| Persona button doesn't seem to change tone | Very short/simple prompt where personas behave similarly | Ask something persona-specific (e.g. a coding question for Python Tutor) to see the difference clearly. |
| Voice input/output not visible in UI | Backend methods (transcribe_audio, text_to_speech) exist but aren't yet wired to a mic widget |
Add an audio input component (e.g. streamlit-mic-recorder) and call bot.transcribe_audio() on the captured bytes. |
πΊοΈ Roadmap and Future Work
- Firebase Authentication β real accounts instead of a bookmarkable session link, so memory follows a student across devices.
- Voice mode β wire the existing Whisper/gTTS backend into a mic-input widget in the UI.
- Multi-document Q&A β support asking questions across several uploaded files at once.
- Persona customization β let students write or tweak their own persona system prompts.
π€ Author
Built by Aazan Khan β BS Computer Science student at International Islamic University Islamabad (IIUI), focused on Generative AI application development.