Guide
Architecture
The backend is organized as ports and adapters: the core knows only interfaces, and one composition root connects them to Qdrant, the parsers, OCR and the model clients.
| Layer | What lives there |
|---|---|
| Domain | Documents, sections, query modes, upload policy, runtime settings, errors |
| DTOs | Validated requests and typed responses |
| Ports | Repository, parser, chunker, condenser, model gateway, progress, reranker, runtime settings store |
| Use cases | One class per operation: ingest, answer, suggest questions, reuse, delete, configure the model, list Ollama models, change runtime settings, show a cited image… |
| Strategies | Strict, Hybrid and Open conversation pipelines; citations; context budget; Persian normalization |
| Adapters | Qdrant and BM25, LlamaIndex model clients, FlashRank reranker, PDF/Office/OCR parsers |
| API | FastAPI routes, middleware, error mapping and server-sent events |
Compose defines three containers: the app, Qdrant and Ollama, which runs only with the local-model profile. Instead of the Ollama container, the app can use the Ollama installed on the host, reached at host.docker.internal; the host's models and GPU are then used directly. Failures are reported as ollama_url_not_allowed or ollama_unreachable.
HTTP API
| Endpoint | Purpose |
|---|---|
| GET /health/live, /health/ready | Liveness, and readiness once models and Qdrant are available |
| GET /capabilities | Upload limits and supported file types |
| GET, PUT /models/configuration | Read or verify and apply the model connection |
| GET /models/ollama | The installed Ollama models |
| GET, PUT, DELETE /settings/runtime | Read, change or reset the settings changed in the app |
| POST /ingest | Upload and index files |
| POST /query, /query/stream | Answer a question, at once or streamed |
| POST /sessions/{id}/suggestions | Three questions the documents can answer |
| POST /sessions/{id}/files/reuse | Copy an indexed document from another conversation |
| GET /sessions/{id}/images/{n} | The image a cited passage was read from |
| GET, DELETE /sessions/{id}/files | List or delete a conversation's documents |
| DELETE /sessions/{id} | Delete a conversation's index |
A streamed answer
POST /query/stream sends server-sent events in order: stage (understanding, retrieving, generating), sources, token for each piece of text, then done with the full answer, its outcome and the cited passage numbers. Errors arrive as an error event with a stable code.
Every error response has a stable code next to its message, so the interface can explain it in your language.