Architecture
RAG Pipeline
The assistant processes user queries through a Retrieval-Augmented Generation pipeline:
- Upload — files are uploaded via
POST /upload, parsed, and chunked. Images are captioned via the vision model. - Index — chunks are embedded and stored in Qdrant as vector documents
- Chat — at query time, relevant chunks are retrieved and injected into the prompt; the LLM autonomously calls skill tools to fetch live data
- Stream — the response is streamed back to the client via SSE
All of it shares one Qdrant collection: curated training material, administrator-shared files, and every member's own uploads. What separates them is metadata that the retrieval query does not currently read — see the companion's knowledge before changing anything on this path.
Component Overview
| Component | Module | Role |
|---|---|---|
| FastAPI application | main.py |
HTTP server (create_app factory), route registration, lifespan hooks |
| RAG pipeline | rag.py |
LlamaIndex index, retrieval, query engine |
| Auth | auth.py |
JWT verification via trusted headers or JWKS |
| History | history.py |
Conversation and message persistence |
| Uploads | uploads.py |
File storage, attachment management |
| Chat streaming | openai_stream.py |
SSE token streaming with agentic tool-calling loop |
| Vision | openai_vision.py |
Image captioning via the vision model |
| Model endpoint | llm.py |
Clients for the configured OpenAI-compatible endpoint, embeddings, startup check |
| Document processing | document_processing.py |
MIME detection and text extraction for uploads |
| Skills | skills/ |
Modular skill system: Digital Twin, Weather, Flexibility, REC Registry, Documents |
| Suggestions | suggestions.py |
Localized prompt suggestions and tool labels |
| Knowledge bases | kb_collections.py |
Per-community alias naming, embedding fingerprint, generations, startup check (ADR-0008) |
| Knowledge sources | kb_sources.py, kb_store.py |
Registered git/directory sources per community; incremental Markdown indexing |
| Attachment indexing | attachment_index.py |
Extraction and indexing shared by uploads and rebuilds |
| Knowledge-base operations | kb_admin.py, cli.py |
celine-assistant kb: status, sync, reindex, prune, migrate-legacy |
| Settings | settings.py |
Pydantic-settings environment configuration |
Modules that are not part of the pipeline
Present in src/, reachable from nothing, and easy to mistake for the supported path:
| Module | What it looks like | What it is |
|---|---|---|
src/celine/assistant/skills/datasets.py |
a dataset-query skill | deliberately disabled — dataset-api needs a service token, and this service holds only the caller's (ADR-0005) |
Deleting them is owed work, not a decision to re-take.
Frontend
This repository is a pure API backend. The chat UI is maintained separately in celine-frontend:
apps/assistant— standalone full-page assistant app
The frontend communicates with this API at apiBaseUrl.
Service Dependencies
| Service | Purpose |
|---|---|
Model endpoint (OpenAI-compatible, LLM_BASE_URL) |
Chat completions, text embeddings, and vision (image captioning) |
| Qdrant | Vector storage and similarity search |
| PostgreSQL | Conversation history, attachment metadata |
| Digital Twin | Energy data, weather, and forecast queries via skills |
| REC Registry | Membership, assets, and delivery point queries via skills |
| Flexibility API | Load-shift suggestions and gamification via skills |
| Keycloak / oauth2_proxy | JWT authentication |
Data Flow
Upload path:
POST /upload -> parse file -> (if image: caption via vision model) -> split into chunks -> embed (model endpoint) -> upsert (Qdrant) -> store metadata (PostgreSQL)
Chat path:
POST /chat -> verify JWT -> load history -> load authorized attachments -> retrieve context (Qdrant) -> build prompt -> stream (model endpoint, SSE with agentic tool-calling loop)
Database Models
PostgreSQL (async via SQLAlchemy + asyncpg). Alembic handles migrations. Models:
Conversation— linked to a user identity, the verified token'ssubclaim (REQ-0047)Message— role (user/assistant), content, timestamp, optional attachment refsAttachment— file metadata: name, MIME type, Qdrant collection reference, scope (user/system)