MojarMojar
Developers

Developer overview

How Mojar fits together: the web app, the RAG API, and supporting services.

Mojar is a multi-service platform. This page maps the system for engineers so you know where to look when you need to integrate, extend, or debug.

Services at a glance

mojar.ai

Next.js 14 web application — chat UI, agent management, embed widget, and API routes for the embed session and token lifecycle.

RAG-API

NestJS application that owns document ingestion, embedding, retrieval, and context assembly. Backed by a Python FastAPI service for ML workloads.

Supabase

Shared Postgres database, auth, and file storage. Both mojar.ai and RAG-API connect to the same Supabase project.

What runs where

ServiceTechnologyRole
Web appNext.js, AI SDK, Supabase AuthChat interface, agent configuration, embed widget host
RAG API — NestJSNestJS, BullMQ, RedisIngestion orchestration, embedding coordination, retrieval pipeline, HTTP API
RAG API — PythonFastAPI, HuggingFaceML embedding models, chunk processing
Document parserApache Tika (containerised)Extracts plain text from uploaded files (PDF, DOCX, etc.)
File-import companionUppy CompanionProxies cloud storage imports (Google Drive, Dropbox, OneDrive, Box) from the browser
Queue / workerBullMQ + RedisAsync job queues for document embedding and housekeeping tasks
DatabaseSupabase (Postgres + pgvector)Stores agents, documents, chunks, embeddings, and chat history

End-to-end RAG flow

When a user uploads a document and then sends a chat message, the platform executes this pipeline:

Ingest

The user uploads a file via the web app. The file is stored in Supabase Storage and a documents record is created with status processing.
The RAG-API NestJS service receives an ingest request and places a job on the BullMQ queue.
A queue worker picks up the job and sends the file to Apache Tika for text extraction. For cloud-provider files, the Uppy Companion service proxies the download first.

Process and embed

The extracted text is split into overlapping chunks and stored in the chunks table.
Each chunk is sent to the Python FastAPI service, which generates a vector embedding using a HuggingFace model.
Embeddings are written back to the chunks table (Postgres pgvector column). The document status advances to completed.

Retrieve and answer

When the user sends a chat message, the web app calls the RAG-API retrieval endpoint with the agent ID and the user query.

The RAG service runs a similarity search (cosine distance via pgvector) against the agent's chunks, then optionally re-ranks results for relevance. Adjacent chunks are "sibling-dragged" — the chunks immediately before and after each matched chunk are fetched and merged so the LLM receives full context windows rather than isolated fragments.

The assembled context and user query are forwarded to the LLM (OpenAI, Anthropic, Google, or DeepSeek, depending on agent configuration). The response streams back to the web app with source citations attached.

Key concepts for integrators

Agents are the central object. Each agent has its own knowledge base (a set of documents), an LLM configuration, and optionally a set of allowed embed domains. An agent is identified by its UUID.

Domains gate the embed widget. Before a widget on an external site can open a session, the calling origin must be registered as an allowed domain for that agent. Each allowed domain has its own domainUuid which is required alongside agentUuid in the loader script.

Session tokens are short-lived JWTs (25-minute lifetime) issued by POST /api/embed/initiate-session. The loader script handles token acquisition and silent refresh automatically.

Next steps

On this page