File size: 2,872 Bytes
4b21338 a585654 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | ---
title: LibBee
emoji: π
colorFrom: blue
colorTo: yellow
sdk: docker
app_file: app.py
pinned: false
---
# π LibBee β KU Library AI Assistant
An open-source, institution-aware AI library assistant for Khalifa University Library, Abu Dhabi, UAE.
Built with FastAPI, hybrid FAISS + BM25 RAG, and live LibCal integration.
**Live interface:** https://ku-library.github.io/LibBee
**GitHub:** https://github.com/ku-library/LibBee
---
## Architecture
- **Backend:** FastAPI + Python 3.9 (this Space)
- **Frontend:** GitHub Pages (single-file HTML/JS)
- **RAG:** FAISS dense + BM25 sparse + RRF fusion
- **Live data:** LibCal API via Cloudflare Worker proxy
- **Analytics:** Cloudflare D1
## Secrets required
Set these in the Space **Settings β Variables and Secrets**:
| Secret | Description |
|---|---|
| `OPENAI_API_KEY` | Required for classification and answering |
| `ANTHROPIC_API_KEY` | Optional β enables Claude Haiku toggle |
| `PRIMO_API_KEY` | Required for PRIMO discovery search |
| `ADMIN_PASSWORD` | Required for /admin dashboard |
| `CLOUDFLARE_WORKER_URL` | Required for live hours/events and analytics |
| `SESSION_SECRET` | Required for admin session |
## Version
**v3.7** β Navigation-first agentic AI. See GitHub for changelog.
## Architecture (v3.8)
The pipeline is split by stage under `src/agentcore/` - each module's docstring
explains its role:
| Module | Role |
|---|---|
| `models.py` | Pydantic I/O contracts |
| `constants.py` | Regexes, URLs, prompts (no logic) |
| `utils.py` | Shared helpers, LLM factory, query/URL builders |
| `classify.py` | Rule pre-classifier + LLM intent classifier |
| `libcal.py` | Live hours/events via Cloudflare Worker proxy |
| `scholarly.py` | OpenAlex, Semantic Scholar, Crossref, Unpaywall clients |
| `rendering.py` | HTML fragments (badges, trace blocks, AI-tools footer) |
| `intents_library.py` | library_info handlers |
| `intents_search.py` | search_academic / search_medical machinery |
| `intents_general.py` | general / social handlers |
| `orchestrator.py` | Injection gate, routing pipeline, analytics logging |
`src/api/agent.py` is a thin router. Tests: `pytest tests/ -q` (20 tests, no
API keys required).
## Environment variables (new in v3.8)
| Variable | Purpose |
|---|---|
| `CLOUDFLARE_WORKER_TOKEN` | Bearer token for the Worker analytics surface; must equal the Worker's `ANALYTICS_TOKEN` secret |
| `CONTACT_EMAIL` | Polite-pool contact sent to OpenAlex / Unpaywall / Crossref (default `library@ku.ac.ae`) |
## Privacy
Before any query reaches metrics or the D1 analytics store it passes
`_redact_for_analytics`: e-mail addresses and digit runs of 6+ are masked and
text is truncated to 200 characters. Answer excerpts logged for the daily
relevance agent get the same treatment. The Worker applies the identical
redaction server-side as defence in depth.
|