Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
aabd208
first commit
Conwenu Sep 24, 2025
dbe08ca
Changed README.md
Conwenu Sep 24, 2025
749a260
Updated README.md
Conwenu Sep 24, 2025
39083c5
Update README.md
Conwenu Sep 24, 2025
034b75a
updated the llm service and added ollama
Conwenu Sep 25, 2025
923625f
Merge branch 'main' of https://github.com/Conwenu/AskTemoc_Backend
Conwenu Sep 25, 2025
a29fc90
scraper
davis118 Nov 6, 2025
2052b4d
Merge pull request #1 from davis118/main
davis118 Nov 6, 2025
f812faf
Create embedding.py
Sal-Fakoya Nov 6, 2025
53b0073
Rename embedding.py to embedding_service.py
Sal-Fakoya Nov 6, 2025
52cf57f
test branch main
AliBenrami Nov 6, 2025
0d159ee
new file: .env.example
Jay-41 Nov 13, 2025
ab7c5f7
added the general web scraping
Conwenu Nov 16, 2025
0e514cb
added the html document chunking class
Conwenu Nov 16, 2025
a7e7157
Updated README with setup instructions and included new dependencies …
Conwenu Nov 16, 2025
f3c00b9
Document recent updates: README setup, new dependencies, HTML chunkin…
NextDev65 Nov 19, 2025
d6acad2
Implement RAG chat endpoint: streaming responses, prompt template, ch…
NextDev65 Nov 20, 2025
f805c6a
feat(rag): integrate ChromaDB ingestion and Ollama streaming pipeline
NextDev65 Nov 20, 2025
18165a7
chore(db): add chroma db verification script
NextDev65 Feb 3, 2026
37b9b1f
feat(api): add health check endpoint and enable CORS
NextDev65 Feb 4, 2026
a13341d
chore(chromadb): align ChromaDB configuration with environment variables
NextDev65 Feb 14, 2026
9de69bc
chore(chromadb): fully remove Pinecone and standardize on ChromaDB
NextDev65 Feb 17, 2026
57d4b91
housing scraper
sainikhil1611 Feb 18, 2026
58907de
docs(chromadb): update documentation to reflect full ChromaDB migration
NextDev65 Feb 19, 2026
c7297a3
docs(quickstart): restructure setup guide and clarify local developme…
NextDev65 Feb 19, 2026
77eba34
Merge pull request #4 from davis118/housing_scraper
NextDev65 Apr 9, 2026
4e40f1d
added openai support and put into docker container
davis118 Feb 26, 2026
806fef6
Merge pull request #2 from davis118/feature/openai-docker
NextDev65 May 1, 2026
0415dde
fix(chat): reliable SSE parsing, markdown rendering, working dev setup
davis118 Sep 24, 2026
6edd28b
chore: move catalog data to data/catalog and set scraper aside for su…
Sal-Fakoya Oct 5, 2026
f8804aa
Add 'backend/' from commit '806fef6bbd5a641b7a054e46660fdf7db79f5b58'
Sal-Fakoya Oct 5, 2026
cda0308
chore: relocate catalog scraper, dedupe catalog data, untrack app/.env
Sal-Fakoya Oct 5, 2026
c935485
build(backend): UTF-8 lean requirements.txt, split scrape and dev deps
Sal-Fakoya Oct 5, 2026
d6784d7
feat(data): map catalog folders to program URLs in sources.json
Sal-Fakoya Oct 5, 2026
9b4838f
refactor(backend): pydantic-settings config and lazily built RAG serv…
Sal-Fakoya Oct 5, 2026
6b629af
fix(chat): stream answer deltas off the event loop, end with done event
Sal-Fakoya Oct 5, 2026
d7951db
feat(backend): idempotent seed_catalog script for the vector store
Sal-Fakoya Oct 5, 2026
1d138a5
fix(seed): smaller default embedding batches, --batch-size, readable …
Sal-Fakoya Oct 5, 2026
23a0f07
feat(api): require signed bearer token on /api/chat, persist users
Sal-Fakoya Oct 5, 2026
f6c4036
fix(config): never echo settings input in validation errors
Sal-Fakoya Oct 5, 2026
4f9c7fd
feat(web): UTD sign-in with Auth.js and authenticated API proxy
Sal-Fakoya Oct 5, 2026
7e6e833
test(backend): auth, SSE, health, users, config guard and seed tests
Sal-Fakoya Oct 5, 2026
76a1fe8
build: docker-compose for the API with persistent state and optional …
Sal-Fakoya Oct 5, 2026
c89085e
chore: setup/seed/api/web/test dev scripts for bash and PowerShell
Sal-Fakoya Oct 5, 2026
9ec3170
ci: run backend pytest and frontend lint + build on PRs to main
Sal-Fakoya Oct 5, 2026
34e2019
fix(chat): also accept delta-style text events from older API builds
Sal-Fakoya Oct 5, 2026
4a162a7
docs: root README quickstart, auth setup guide, known issues
Sal-Fakoya Oct 5, 2026
7216e18
Revert "feat(web): UTD sign-in with Auth.js and authenticated API proxy"
Sal-Fakoya Oct 6, 2026
9a22e04
Revert "feat(api): require signed bearer token on /api/chat, persist …
Sal-Fakoya Oct 6, 2026
44fa978
fix(web): proxy to the local API under next dev
Sal-Fakoya Oct 6, 2026
86fc7df
test(backend): drop auth tests now that sign-in is out of the baseline
Sal-Fakoya Oct 6, 2026
db2918d
docs: describe the baseline without sign-in
Sal-Fakoya Oct 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Shell scripts must keep LF endings to run on macOS/Linux/CI.
*.sh text eol=lf
Makefile text eol=lf
49 changes: 49 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: CI

on:
pull_request:
branches: [main]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
backend:
name: Backend (pytest)
runs-on: ubuntu-latest
defaults:
run:
working-directory: backend
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
cache-dependency-path: |
backend/requirements.txt
backend/requirements-dev.txt
- run: pip install -r requirements-dev.txt
- run: python -m pytest

frontend:
name: Frontend (lint + build)
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
cache-dependency-path: frontend/package-lock.json
- run: npm ci
- run: npm run lint
- run: npm run build
32 changes: 32 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,33 @@
.vercel

# Secrets / local config (commit only *.env.example)
.env
.env.*
!.env.example
!frontend/.env.production

# Python
__pycache__/
*.py[cod]
.venv/
venv/
.pytest_cache/
*.egg-info/

# Backend runtime state (vector store, SQLite)
backend/app/chroma_db/
backend/*.db

# Scraper output (committed corpus lives in data/)
backend/scrapers/catalog/output/
backend/scrapers/catalog/test_output/

# Node
node_modules/

# IDE / OS
.vscode/
.idea/
.DS_Store
Thumbs.db
*.log
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Thin wrapper; the logic lives in scripts/dev.sh (Windows: scripts/dev.ps1).
.PHONY: setup seed api web test
setup seed api web test:
@scripts/dev.sh $@
145 changes: 145 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# Ask Temoc

Ask Temoc is a chatbot that answers UT Dallas students' questions about degree
programs, grounded in the UTD undergraduate catalog. It's built by the UTD AI
Society.

## Architecture

```
browser ──► Next.js (frontend/) ──► FastAPI (backend/) ──► Chroma vector store
/api/proxy/* rewrite RAG chain (LangChain) seeded from data/catalog
OpenAI or Ollama
```

- **The browser calls the web app's own `/api/proxy/*`.** Next.js forwards those
requests to the API (`ASKTEMOC_API_ORIGIN`): `http://localhost:8000` under
`npm run dev`, Cloud Run in production builds.
- **The API** retrieves catalog chunks from Chroma and streams an answer with its
sources as server-sent events.
- **Models.** If `OPENAI_API_KEY` is set, the API uses OpenAI for chat and
embeddings; otherwise it uses a local [Ollama](https://ollama.com).
- **No sign-in yet.** There's no app-level sign-in; it's planned for Weeks 2-4 of
the 10-week plan. See [docs/KNOWN_ISSUES.md](docs/KNOWN_ISSUES.md).

```
frontend/ Next.js 15 chat UI
backend/ FastAPI app (app/), seed script (scripts/), tests, catalog scraper (scrapers/)
data/ committed scraped corpus: data/catalog/<program>/{requirements,example}.txt
docs/ KNOWN_ISSUES.md
scripts/ dev.sh / dev.ps1 task runners
```

## Quickstart

You need **Python 3.11**, **Node 20+**, and Docker (optional). You also need
**either** an OpenAI API key with billing enabled **or** a local Ollama.

All commands below run from the repo root. They're written for macOS/Linux/Git
Bash; on Windows PowerShell, replace `scripts/dev.sh` with `.\scripts\dev.ps1`.

**1. Clone and install.**

```bash
git clone https://github.com/aisutd/asktemoc.git
cd asktemoc
scripts/dev.sh setup
```

This creates `backend/.venv` and installs backend and frontend dependencies. It
also copies `backend/.env.example` to `backend/.env` and `frontend/.env.example`
to `frontend/.env.local`. Both copies are gitignored; never commit them.

**2. Choose a model provider** in `backend/.env`. Either:
- set `OPENAI_API_KEY`, or
- leave it empty and pull the two default Ollama models:
`ollama pull llama3.1:8b && ollama pull nomic-embed-text`.

Every other setting has a working default. The frontend needs no env vars for
local development.

**3. Seed the vector store** from the catalog files in `data/catalog/`:

```bash
scripts/dev.sh seed
```

This prints document and chunk counts (193 documents and 2047 chunks today).
Re-running is safe: it replaces the chunks rather than duplicating them. If you
switch between OpenAI and Ollama (or change the embedding model), run this
again; vectors from different models can't be mixed, and the API logs a warning
if they don't match.

**4. Start the API and the web app** in two terminals:

```bash
scripts/dev.sh api # http://localhost:8000
scripts/dev.sh web # http://localhost:3000
```

**5. Try it.** Open <http://localhost:3000>, click **Get Started**, and ask
*"What are the core requirements for the BS in Computer Science?"* The answer
streams in with linked sources.

You can also call the API directly, for example from scripts:

```bash
curl -N -X POST localhost:8000/api/chat -H 'content-type: application/json' \
-d '{"message":"core requirements for BS Computer Science"}'
```

### Running the API in Docker instead

```bash
docker compose up --build api
docker compose run --rm api python scripts/seed_catalog.py
```

The container reads `backend/.env`. Its vector store and database live in a
Docker volume. It reaches Ollama on your host by default; `docker-compose.yml`
shows how to use an Ollama container instead.

## Tests and CI

```bash
scripts/dev.sh test # backend pytest, then frontend lint + build
```

The backend tests run offline: the RAG chain is faked, and nothing calls OpenAI,
Ollama or the network. On every pull request to `main`, GitHub Actions runs the
same checks (`.github/workflows/ci.yml`).

## Chat API

`POST /api/chat` with body `{"message": "..."}` returns `text/event-stream`.
Each event is one line, `data: {json}`:

| `type` | Fields | Meaning |
| --- | --- | --- |
| `source` | `message` (`"Source n: <url>"`), `index`, `url`, `title?` | one retrieved chunk, sent before the answer |
| `text` | `message` | the next piece of the answer; append it |
| `done` | | end of stream |

Clients should ignore unknown types. `GET /api/health` works with or without the
trailing slash.

## Deployment

The frontend deploys to Vercel and the API to Cloud Run.

**Vercel:** `ASKTEMOC_API_ORIGIN` is already committed in `vercel.json` and
`frontend/.env.production`, so no extra variables are needed. Until app-level
sign-in exists, visitors are gated by Vercel Deployment Protection (Project →
Deployment Protection → Vercel Authentication). Run `vercel link` /
`vercel deploy` from the repository root with the project's Root Directory set
to `frontend`.

**Cloud Run:**
- `ENVIRONMENT=production`
- `OPENAI_API_KEY`
- `CORS_ORIGINS=https://<your Vercel domain>`
- `DATABASE_URL`, plus `CHROMA_PERSIST_DIRECTORY` on persistent storage, seeded
with `scripts/seed_catalog.py`

The API has no authentication, so anyone who knows its URL can use it. See
[docs/KNOWN_ISSUES.md](docs/KNOWN_ISSUES.md).
11 changes: 11 additions & 0 deletions backend/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.env
**/.env
**/__pycache__
**/*.pyc
.venv
venv
app/chroma_db
*.db
scrapers
tests
.pytest_cache
29 changes: 29 additions & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copy to backend/.env and fill in. backend/.env is gitignored; never commit it.
# Every value here is optional unless marked required; defaults are shown.

ENVIRONMENT=development

# --- LLM + embeddings ------------------------------------------------------
# If OPENAI_API_KEY is set, chat and embeddings use OpenAI; otherwise Ollama.
# Switching provider (or embedding model) requires re-running
# `python scripts/seed_catalog.py`: vectors from different models don't mix.
OPENAI_API_KEY=
OPENAI_MODEL=gpt-4o-mini
OPENAI_EMBEDDING_MODEL=text-embedding-3-small

OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=llama3.1:8b
OLLAMA_EMBEDDING_MODEL=nomic-embed-text

# --- Storage ----------------------------------------------------------------
# Relative paths resolve against backend/. Postgres works by changing the URL,
# e.g. postgresql+psycopg://user:pass@host/asktemoc (install the driver).
DATABASE_URL=sqlite:///./asktemoc.db
DB_ECHO=false
CHROMA_PERSIST_DIRECTORY=./app/chroma_db
CHROMA_COLLECTION_NAME=asktemoc_collection

# --- HTTP -------------------------------------------------------------------
# Comma-separated. The browser only talks to the Next.js server, so this rarely
# needs more than the web origin.
CORS_ORIGINS=http://localhost:3000
25 changes: 0 additions & 25 deletions backend/.gitignore

This file was deleted.

Loading
Loading