Guide

From clone to first customer

Install cob-rag-engine on your own machine, sign in, onboard a customer with a working chat widget, and keep it running. Every command, port and setting on this page was checked against the repository.

Checked against the repository on 2 October 2026. Tell the guide how you will set things up and it shows only the steps and commands that apply to you; every tab and command follows your choices. Prefer to read everything? Switch on “Show all options”.

Where to get it
Get cob-rag-engine from its repository (git clone https://github.com/callobuzz/cob-rag-engine.git) or download a release zip, then cd cob-rag-engine. The steps below run from that folder. Questions: callobuzz@gmail.com.

01What you’ll have running#

cob-rag-engine is a self-hosted knowledge engine. Each business you serve (a customer, called a tenant in the API) gets private knowledge bases: its documents go in, and cited answers come out through a website chat widget, your own app, or an AI agent. You run one Docker Compose stack: the engine API, a background worker, a mailer, a scheduler, a web scraper, the dashboard, and the datastores (PostgreSQL, Valkey (a Redis-compatible store), Qdrant and the embedding container). This guide takes you from the code you cloned or unzipped to a first customer with a working widget, then covers day-to-day running and what to do when something breaks.

Windows and macOS are for trying cob-rag-engine on your own computer, which is what this guide does. A live server runs Linux: see the requirements and install it with one command from the deploy guide.

ServiceAddressWhat it is
Dashboardhttp://127.0.0.1:8090Where you and your customers sign in. Port variable RAG_DASHBOARD_HOST_PORT.
Engine APIhttp://127.0.0.1:8000The REST API. Interactive docs at /docs while RAG_ENV=dev. Port variable RAG_APP_HOST_PORT.
Web scraperhttp://127.0.0.1:8001Crawls a customer’s website for the dashboard’s Crawler page. Port variable RAG_SCRAPER_HOST_PORT.
Embeddings (TEI)127.0.0.1:8081The embedding model container (profile tei, on by default).
Langfusehttp://127.0.0.1:3002Optional: traces of every question (profile observability).
Whisper127.0.0.1:9010Optional: audio transcription (profile transcription). Port variable RAG_WHISPER_HOST_PORT.
Datastores5433 6380 6333/6334PostgreSQL, Valkey and Qdrant. You never need to open these.
Good to know
Every port is published on 127.0.0.1 only (RAG_BIND_ADDR), so only your own machine can reach the stack. The three web ports are configurable through RAG_APP_HOST_PORT, RAG_SCRAPER_HOST_PORT and RAG_DASHBOARD_HOST_PORT; step 4 shows how the wizard changes them for you. The other ports are fixed in docker-compose.yml.

Back to top

Start hereYour setup#

The setup wizard asks different questions depending on your computer and your answers, and the steps after it change with them. Say how you will answer and this guide shows only what applies: the right commands for your system, where your sign-in link will arrive, and what to do about a missing AI key. Your choices stay in this browser and in the page address; nothing is sent anywhere.

JavaScript is off, so every variant is shown and each one is labelled with the setup it applies to.

Showing the guide for

Windows (Git Bash) · quick

Your computer

Sets the commands you see. We guessed from your browser.

Wizard mode

Quick asks the essentials. Full also asks about embeddings, storage, addresses and optional services.

NVIDIA GPU Docker can use

Not sure? Choose No, or run the check in “Your machine”.

Macs have no NVIDIA GPU that Docker can use, so choose No.

Super-admin e-mail

The account you sign in to the dashboard with.

E-mail sending

Skipped is fine on your own machine: codes and links go to the mailer log.

AI model key

Without a key, uploading and searching work; answering does not.

Re-ranker

Off is the safe start. You can change it per knowledge base later.

Full mode only

Embeddings

On Docker Desktop for Windows, TEI’s CUDA image cannot see the GPU, so the wizard defaults to the in-engine model.

File storage
Host ports

Defaults are 8000, 8001 and 8090.

Optional services

Back to top

02Before you start#

2.1Software#

  • Docker with Compose v2: Docker Desktop on Windows or macOS, Docker Engine on Linux. You need the docker compose command (two words), not the old docker-compose.
  • Python 3.10 or newer, only for the setup wizard. The wizard uses the standard library, so there is nothing to pip install and no virtualenv to create.
  • git, only if you keep your copy under version control.
  • make is optional. make setup is only a shortcut for python scripts/setup.py.

Check what you have:

Terminal
docker --version
docker compose version
python --version
git --version
Tip
If python is not found, install Python 3.10 or newer (on Windows tick “Add python.exe to PATH” in the installer). On macOS and Linux the command is often python3; make setup uses python when it works and python3 otherwise, so it needs no change; without make use the python3 scripts/setup.py form.

2.2Your machine#

  • Memory: 4 GB of RAM or more for Docker. The default stack measured 2.1 GB on CPU with 270,000 chunks indexed. Turning on the local re-ranker on CPU adds about 2.3 GB.
  • Disk: the repository does not state a figure. The first start builds three images and downloads several more plus an embedding model, so keep several GB free. Ten GB is a comfortable margin; that number is a rule of thumb, not something we measured.
  • An NVIDIA GPU is optional. It only makes the local models faster (the embedding model and a local re-ranker), not better. Hosted APIs and LLM re-ranking run at the provider either way. To see whether Docker can use your GPU, run this (it is the same check the wizard suggests; it downloads a small image the first time):
Terminal
docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi

If it prints a table with your GPU, Docker can use it. If it fails, answer “no” to the GPU question later; everything works on the CPU.

You chose no GPU, so skip this check: everything local runs on the CPU. If you get one later, re-run the wizard and answer yes.

No NVIDIA GPU on a Mac
Docker on a Mac cannot use an NVIDIA GPU. Choose “No” in your setup; everything runs on the CPU.

2.3An AI model key#

Answers are written by a language model, so you need one provider key: OpenRouter (one key, hundreds of models), OpenAI, Anthropic (Claude), Google Gemini, or a local Ollama with no key at all. You can skip this during setup: uploading and searching work without a key, and only answering needs one. The key is stored in your local .env file and nowhere else.

You said you will add one, so have the key ready before step 4: the wizard asks for it (hidden as you type).

You chose to skip it for now. Do step 4 without a key and add it afterwards; Ask in the playground shows how.

Back to top

03Get the code#

Clone the repository (or unzip a release zip) and move into its folder. Every command in the rest of this guide runs from this folder.

Terminal
cd cob-rag-engine

Back to top

04Configure with the setup wizard#

The wizard asks a few questions, generates every secret, and writes one file: .env in the repository root. Keys you type are hidden and never printed back.

4.1Run it#

Git Bash
python scripts/setup.py
# or, if make is installed: make setup
PowerShell
python scripts/setup.py
Terminal
python3 scripts/setup.py
# or: make setup

It opens with “How much do you want to set up?” Choose Quick, the default (or run it with --quick to skip that menu).Choose Full (or run it with --full to skip that menu). Press Enter to accept the answer in [brackets] at any prompt.

4.2Quick or full#

  • Quick (the default, recommended): the GPU question once, then your e-mail, the AI model, how to send e-mail, and the re-ranker. Start here.
  • Full: also asks about the environment (development or production), where embeddings run, where uploaded files are stored, the web addresses and host ports, the network bind address, and the optional services (audio transcription, Langfuse) and the answer-quality evaluation add-on. Choose it with --full; --quick forces quick mode.

4.3What each answer means#

GPU
“Do you have an NVIDIA GPU that Docker can use?” It is asked once, first, and yes / no / not sure (not sure is treated as no and prints the check from step 2). The answer decides three things: whether the start command includes the GPU overlay, whether the bundled embedding container (TEI) uses its CUDA image, and where a local re-ranker runs. --gpu yes or --gpu no answers it up front.
Super-admin e-mail
The account you sign in to the dashboard with, for example admin@yourcompany.in. It gets a link to set its password. It must be a real address: names that never receive mail (.local, .test, .example, .localhost, .invalid) are accepted only when the environment is development (RAG_ENV=dev) and refused in production, and the wizard asks again. Press Enter to skip; you then sign in with the admin API key instead (step 6).
AI model
Pick a provider, the model that writes answers, and a fast model; the wizard suggests both per provider (answers / fast: OpenRouter openai/gpt-oss-120b / openai/gpt-6-luna, OpenAI gpt-6.1-sol / gpt-4.1-mini, Anthropic claude-sonnet-5-5 / claude-haiku-4-5, Gemini gemini-3.8-flash / gemini-3.5-flash-lite, Ollama llama3.1 / llama3.2). The fast model is a small, quick model from the same provider that rewrites the search question before it is searched (RAG_LLM_FAST_MODEL); Use a small non-thinking model here: it labels every message and suggests follow-ups; a thinking model makes replies slow. Budget option. On OpenRouter the wizard shows two fast models as a numbered choice and defaults to the first: openai/gpt-6-luna (recommended, 98.9% accurate, about ₹13.6 per 1,000 messages) and google/gemma-4-26b-a4b-it (64% cheaper, about ₹4.9 per 1,000, 97.7% accurate); the numbers come from the fast-model benchmark. Thinking is one setting for every model: RAG_LLM_THINKING for answers and RAG_LLM_FAST_THINKING (default off) for the fast model, each off, minimal, low, medium, high or provider-default, and per knowledge base under Model & keys. Off is fastest and cheapest; turn it on only for hard questions. A model that cannot stop thinking (gpt-oss, Gemini 3 Flash) runs at its lowest setting, and every answer says what it ran at. A model per language: on OpenRouter the wizard also asks whether Hindi and Hinglish replies should use their own model (default yes, google/gemma-4-31b-it, written to RAG_LLM_LANGUAGE_MODELS). The assistant notices the language of each message, so Hindi (Devanagari) and Hinglish (Hindi in English letters) are answered by Gemma 4 31B, which had the best Hindi tone and the fastest first word in the answer benchmark, while English keeps the main model (openai/gpt-oss-120b by default, at thinking low). The chosen model answers at its lowest thinking setting, wherever the assistant answers (the plain query, widget and conversation endpoints included). Change it per knowledge base under Model & keys → Model per language (the language switch can follow the engine, name a model per language, or be off); the engine page shows the engine's setting. Routing only applies on the engine's own provider: a knowledge base with a key for another company keeps its model unless you name models for it. The engine skips the rewrite altogether for greetings and questions of three words or fewer. Then paste the key, which is hidden. For Ollama it asks for the address, http://host.docker.internal:11434 by default, because from inside Docker your machine is host.docker.internal. Choose “Skip for now” to add the key later as RAG_LLM_API_KEY in .env.
E-mail sending
E-mail carries sign-up codes, password resets and invitations. Skip is fine on your own machine: in development the codes and links go to the logs (step 7 shows where). Gmail or Google Workspace needs an app password (2-step verification on, then create one). Another SMTP server asks for host (for example smtp.zoho.in), port, connection security, login and a sender such as Shree Labs <no-reply@shree-labs.in>.
Re-ranker
A second pass that re-reads the top search results and reorders them. Off is the safe start. In the project’s benchmarks the local model helped on question-and-answer data (the chatbot case) and hurt on other kinds of search; re-ranking through your LLM has not been measured yet. The options follow your GPU answer. With a GPU: off, local on the GPU (about 0.4 s a question), or through your LLM. Without one: off, through your LLM (small cost per question), or local on the CPU (free but about 10 s a question and 2.3 GB of RAM). You can change it per knowledge base later in the dashboard (Knowledge base, then Retrieval).
Embeddings
Quick mode does not ask. It uses the bundled TEI container with the model BAAI/bge-base-en-v1.5, on your GPU if you said yes and on the CPU otherwise. Full mode lets you choose: TEI on CPU, TEI on GPU (offered only if you said yes), inside the engine (BGE-M3), or a hosted API (OpenAI, Cohere, Voyage, Mistral, Gemini or Jina). Changing the embedding model for a knowledge base that already has documents needs a re-embed.
Warning
On Docker Desktop for Windows, TEI’s CUDA image cannot see the GPU (the README says so). If you are on Windows with a GPU, quick mode already handles this: it runs the engine’s own embedding model on the GPU instead of TEI.

4.4Answers for your setup#

The wizard’s questions in the order it asks them, with the answer that matches what you picked in Your setup. Press Enter to take any default.

  1. Environment. “Is this a development machine or a live deployment?” Choose Development. A live deployment needs SMTP (production refuses the log provider) and public https addresses. The deploy guide covers the server, HTTPS and updates.
  2. GPU. “Do you have an NVIDIA GPU that Docker can use?” Choose No. (Not sure is treated as no.)
  3. GPU. “Do you have an NVIDIA GPU that Docker can use?” Choose Yes.
  4. Super admin. “Your e-mail”: type the address you will sign in with, for example admin@yourcompany.in.
  5. Super admin. “Your e-mail”: press Enter to leave it empty. The summary says “skipped (sign in with the admin API key)”.
  6. AI model. “Which AI provider will write the answers?” Pick one, accept or change the suggested model, then paste your key (it is hidden as you type).
  7. AI model. “Which AI provider will write the answers?” Choose the last option, “Skip for now (answers will not work until you add a key)”.
  8. E-mail sending. “How should the engine send e-mail?” Choose “Skip for now (in development, codes and links go to the mailer log)”, the default.
  9. E-mail sending. Choose “Gmail or Google Workspace”. It asks for your Gmail address, an app password (16 characters, hidden; spaces are removed) and the sender shown on e-mails. Create the app password first at myaccount.google.com/apppasswords; 2-step verification must be on.
  10. E-mail sending. Choose “Another SMTP server”. It asks for the server (for example smtp.zoho.in), the port, the connection security (STARTTLS for 587, SSL/TLS for 465), the login and password, and a sender such as Shree Labs <no-reply@shree-labs.in>.
  11. Re-ranker. “Turn on re-ranking?” Choose Off, the default.
  12. Re-ranker. “Turn on re-ranking?” Choose “Local on your GPU”.
  13. Re-ranker. “Turn on re-ranking?” Choose “Local on your CPU (free but slow: ~10 s a question, 2.3 GB RAM)”.
  14. Re-ranker. “Turn on re-ranking?” Choose “Via your LLM key”.
  15. Embeddings. Not asked in quick mode. You get the bundled TEI container on the CPU.You get the bundled TEI container on the GPU.Because you are on Windows with a GPU, the wizard uses the engine’s own embedding model on the GPU, not TEI.
  16. Embeddings. “Where should embeddings be computed?” Choose “Bundled container (TEI) on the CPU”.
  17. Embeddings. “Where should embeddings be computed?” Choose “Bundled container (TEI) on your GPU”.
  18. Embeddings. “Where should embeddings be computed?” Choose “Inside the engine” (BGE-M3, on your GPU if you have one).
  19. Embeddings. “Where should embeddings be computed?” Choose “A hosted API”, then pick the service (OpenAI, Cohere, Voyage, Mistral, Gemini or Jina), accept or change the model and its vector size, and paste that service’s key.
  20. Storage. “Where should uploaded files live?” Choose “On this server”.
  21. Storage. “Where should uploaded files live?” Choose “S3-compatible storage”. It asks for the endpoint address, bucket, region (R2 needs auto), address style, the access and secret keys, and whether to create the bucket automatically.
  22. Web addresses and network. Press Enter through the three host ports, the public address (leave it empty for local use), the three addresses and the bind address (127.0.0.1).
  23. Web addresses and network. Type new numbers for the host ports that clash; the wizard moves the matching addresses and allowed origins. Leave the public address empty for local use and keep the bind address 127.0.0.1.
  24. Optional services. Answer yn to audio transcription and yn to Langfuse. Then Install answer-quality evaluation? (default no): it adds RAGAS and LangChain, about 150 MB, and only the RAGAS scores described under Day-to-day need it.
Re-ranking needs the key
Re-ranking through your LLM runs on the key you skipped. The engine skips LLM re-ranking while no key is set, so add the key before relying on it.

4.5Without the questions#

For scripts, CI or a repeat install, every question can be answered on the command line. --yes accepts every default and asks nothing, --set KEY=VALUE sets any value (repeat it as often as you like), and --dry-run shows what would change, with secrets masked, and writes nothing.

The same answers as one command for your setup. The placeholders (paste-your-key and so on) are yours to replace:

Your setup, no questions

Other examples:

Terminal
python scripts/setup.py --quick --yes --set "RAG_SUPERADMIN_EMAIL=admin@yourcompany.in"
python scripts/setup.py --quick --yes --gpu yes
python scripts/setup.py --dry-run

--yes cannot ask for your LLM key. Add RAG_LLM_API_KEY to .env afterwards, or run the wizard once without --yes. On macOS and Linux write python3 for python.

4.6Running it again later#

Re-running is safe. The wizard copies your old file to .env.backup-<timestamp> first, keeps every value you already have and every key it does not know, and only changes what you answer (it asks “Already set. Keep current?” for things like your key). At the end it prints a summary, a “Worth a look” list of things to double-check, and the exact start command for your choices.

Warning
Keep a safe copy of RAG_ENCRYPTION_KEY from .env. Without it, the LLM keys stored by your customers are unreadable. See backing it up. Never commit .env or paste it into a chat.

Back to top

05Start the stack#

5.1Run the command the wizard printed#

The wizard ends with the exact command for your choices. You said no GPU, so it is the plain one.You said yes to the GPU, so it includes the GPU overlay. make up runs the same command.make up-gpu runs the same command.

Start command
docker compose up -d --build
Start command with the NVIDIA GPU overlay
docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d --build
Optional services
The services you picked start by themselves: the wizard put them in COMPOSE_PROFILES in .env, so the command does not change. Whisper (audio transcription) listens on 127.0.0.1:9010. Langfuse shows its traces at http://127.0.0.1:3002.
Windows with a GPU
On Docker Desktop for Windows the overlay gives the GPU to the engine’s app and worker containers, so the engine’s own embedding model uses it. TEI’s CUDA image cannot see the GPU there, and the wizard did not set it up for you.
TEI cannot use this GPU
On Docker Desktop for Windows, TEI’s CUDA image cannot see the GPU. Re-run the wizard and choose the in-engine embeddings instead.
GPU on Linux
Docker needs NVIDIA GPU support (the NVIDIA Container Toolkit). If Compose says “could not select device driver nvidia”, see The GPU is not used.

5.2The first start takes a while#

The first run builds the engine, scraper and dashboard images and pulls the datastore images, then downloads the embedding model. The compose file gives the embedding container a 120 second grace period before it even checks its health, then 30 checks ten seconds apart, because the model download is the slow part. Models are kept in a Docker volume, so later starts are quick. You can watch it with docker compose logs -f tei. There is no embedding container to wait for here: the engine loads its own embedding model (BGE-M3), which is downloaded too. Embeddings come from the hosted API you chose, so there is no embedding model to download. The local re-ranker model downloads as well.

5.3Wait until it is healthy#

Terminal
docker compose ps

Run it again every minute or so until the app service says healthy. When it does, the engine’s health URL answers in your browser. The engine runs its database migrations by itself as it starts, so there is nothing to migrate by hand. If something stays unhealthy or keeps restarting, jump to reading the logs.

5.4Embedding model#

The default is BAAI/bge-m3 (1024-d, multilingual including Hindi and Hinglish), served by the bundled TEI container, roughly 2.3 GB of weights in memory on CPU (an estimate, not measured). A fresh install needs nothing.

An existing install keeps the model in its own .env (RAG_EMBEDDING_MODEL, RAG_EMBEDDING_DIMENSIONS, RAG_TEI_MODEL_ID), so upgrading the engine changes nothing. To switch, set those to BAAI/bge-m3, 1024 and BAAI/bge-m3 and restart: the daily drift check queues one re-embed migration per knowledge base (GET /api/v1/migrations). Start each with POST /api/v1/migrations/{id}/approve, or all of them with POST /api/v1/admin/migrations/approve-all. It builds the new index beside the old one and swaps once verified, so answers keep working; POST .../rollback undoes it.

Not this
python -m callobuzz_rag.retrieval.reindex --dense is not the way to switch models: it re-embeds with the same model.

Back to top

06First login#

You gave a super-admin e-mail, so you sign in with it once you have set a password. The engine creates the account on its first start and issues a link to set the password.

You skipped the super-admin e-mail, so there is no password account: you sign in to the dashboard with the admin API key.

You skipped e-mail sending, so the engine prints a one-time link in the app’s log instead of sending it:

Git Bash
docker compose logs app | grep -A4 "ONE-TIME SET-PASSWORD"
PowerShell
docker compose logs app | Select-String -Context 0,4 "ONE-TIME SET-PASSWORD"
Terminal
docker compose logs app | grep -A4 "ONE-TIME SET-PASSWORD"

You set up SMTP, so the link is e-mailed to the address you gave and nothing is printed in the log. Check that inbox once the app is healthy.

Gmail
If nothing arrives, look in spam. The engine signs in to Gmail with the app password you created, not your normal password. If it still does not arrive, read the mailer’s log (see Sign-up codes do not arrive).

No e-mail yet? Issue a new link and print it on screen right now:

Terminal
docker compose exec app python -m callobuzz_rag.accounts.bootstrap --resend --print-link

The output shows the account, a link and a code. Open the link, which is valid for 24 hours, and choose a password: 10 to 128 characters, not one of the 10,000 most common, and not containing the name part of your e-mail. Until you set it, every start of the app issues a fresh code and voids the old one, so if you get several, use the newest.

Link expired or used up?

The page says “That code has expired or was used up” when the link is older than 24 hours, a newer link replaced it, or it was tried 5 times. Issue a fresh one and use only that newest link, in a new tab:

Terminal (from the project folder)
docker compose exec app python -m callobuzz_rag.accounts.bootstrap --resend --print-link

It runs inside the app container, so you need nothing installed. If you still cannot get in, sign in with the admin key (step 6.3).

6.2Open the dashboard#

Go to http://127.0.0.1:8090 and sign in with your e-mail and the new password.the admin key from the next step.

Tip
Type 127.0.0.1, not localhost. On Windows with Docker Desktop, localhost resolves to the IPv6 address ::1 first, and the connection resets in a way that looks exactly like the service being down.
Tip
Type 127.0.0.1 rather than localhost: every address in this guide uses it, and it is what the engine’s allowed origins list.

6.3Sign in with the admin keyThe admin key as a fallback#

On the sign-in page click Use an API key instead and paste the admin key, which is RAG_ADMIN_API_KEY in .env. This prints only that one line:

If you lose the password you can still click Use an API key instead on the sign-in page and paste the admin key, which is RAG_ADMIN_API_KEY in .env. This prints only that one line:

Git Bash
grep RAG_ADMIN_API_KEY .env
PowerShell
Select-String RAG_ADMIN_API_KEY .env
Terminal
grep RAG_ADMIN_API_KEY .env
Warning
The admin key can do everything on the engine. Treat it like a root password and do not share your terminal output.

To add an e-mail login later, re-run the wizard with an e-mail, recreate the app, and issue a link:

  1. Terminal
    python scripts/setup.py --quick --yes --gpu no --set "RAG_SUPERADMIN_EMAIL=admin@yourcompany.in"
  2. Terminal
    docker compose up -d app
  3. Terminal
    docker compose exec app python -m callobuzz_rag.accounts.bootstrap --resend --print-link

Back to top

07Try the whole flow#

This walks one customer from sign-up to a working chat bubble. The example is Shree Labs, a pathology lab in Pune. You play two roles: the operator (you, signed in as the super admin) and the customer’s owner. Use a private browser window for the customer so the two sessions do not collide.

7.1Choose how customers join#

The Customers page shows the current sign-up mode; you change it under Sign-up & branding. There are three:

  • Approval required (the default): a new workspace waits as pending until you activate it.
  • Open: the workspace is active the moment the customer verifies their e-mail.
  • Closed: sign-up is refused with your “contact us” text.

You can also skip sign-up: Customers, then Add customer creates an active workspace by hand, and you then invite its owner. That path works even with no e-mail set up, because an invitation sent by the operator shows the accept link on screen.

Where e-mails go
With no SMTP, sign-up codes, activation e-mails, invitations and password resets are written to the mailer’s log (while RAG_ENV=dev) instead of being sent: read them with docker compose logs mailer.With SMTP set up, sign-up codes, activation e-mails, invitations and password resets are sent by e-mail. Operator invitations also show the accept link on screen.

7.2Create a customer#

  1. In the private window open http://127.0.0.1:8090/signup. Enter the business name (Shree Labs), your name, an e-mail that is not the super admin’s (for example owner@shree-labs.in) and a password.
  2. The dashboard asks for a 6-digit code. It works for 10 minutes and 5 tries. It arrives by e-mail at the address you entered (check spam).You have no SMTP, so it is in the mailer’s log:
Git Bash
docker compose logs mailer | grep -A12 "DEV EMAIL"
PowerShell
docker compose logs mailer | Select-String -Context 0,12 "DEV EMAIL"
Terminal
docker compose logs mailer | grep -A12 "DEV EMAIL"

Each message is printed in full after the words DEV EMAIL; take the code from the newest one. Enter it, and the workspace is created with you as its owner.

7.3Activate it#

In approval mode the customer now sees “We’ll activate your workspace soon”. As operator, open Customers, the Pending tab, and choose Activate. Pick a plan and, if you like, add a private note such as “Paid ₹3,000 via UPI on 29 Sep”. The owner gets a “You’re in” e-mail (in the mailer log, as you have no SMTPby e-mail). Activation is not billing: collect payment however you like, then activate.

7.4Create a knowledge base#

As the customer’s owner open Knowledge bases, then New knowledge base, and name it Shree Labs FAQ. A knowledge base has its own documents, model settings, search index and API key. The key is shown once at creation.

7.5Upload something#

Open Add content and drag in a file, for example the lab’s test menu with prices in ₹ and fasting instructions. You watch each file go through queued, parsing, chunking, embedding and done. PDF, Word, PowerPoint, Excel, CSV, HTML, Markdown, plain text, PNG and JPEG are accepted, and audio (mp3, wav, m4a, ogg) when the transcription service is on. You can also crawl a website from Crawler (you review the pages before they go in) or import records from JSON or CSV. See upload size limits before you try a large file. If a file looks like one you already have (the same content, not merely a page from the same site with the same menu and footer), it waits as a possible duplicate and you choose: Replace the old one (it becomes a new version), Keep both, or Skip (don’t add), which drops the upload and adds nothing.

7.6Set up the assistant#

Open the knowledge base, then Assistant, then Guided setup (or press Set up the assistant now right after creating it). Pick a business type, or paste your website and let the engine read it. Confirm what it found (name, phone, WhatsApp, e-mail, hours), then answer the twelve questions, mostly multiple choice. You get a draft in which every item says which answer or page created it, and 15 to 25 automatic checks run against it; a question your documents could not answer is listed as a gap, with a link to add a document or an exact answer. When you are happy, an owner presses Publish. Without an AI model the website step is skipped and the draft is written from the template.

7.7Ask in the playground#

Open Playground, pick the knowledge base, and ask something the document answers, such as “Do I need to fast before a lipid profile?” You get an answer with the passages it used. An owner can also give one knowledge base its own model and key.

Then talk to the assistant the way a visitor would. Say “hi” and it answers at once from its persona, with no model call. Ask a question the document answers and you get an answer with sources. Ask something the documents do not hold, such as a price that is not listed, and it says so honestly, shows no sources and offers a way to reach the business. Ask something unrelated, such as who won a cricket match, and it politely steers back to what it can help with. Prices, dates, times, numbers and names in an answer are checked against the documents sentence by sentence, so one that is not there never reaches the screen.

Add your AI model key first
You skipped the key in step 4, so answering fails until you add one. Open .env and set RAG_LLM_API_KEY to your key (the default provider is OpenRouter; for another provider also set RAG_LLM_PROVIDER and RAG_LLM_MODEL, or re-run the wizard and pick it). Then recreate the services so they read it:
Terminal
docker compose up -d
The website widget needs the same key to answer.
Re-ranking is on
The re-ranker runs on your GPU: about 0.4 s a question.
Re-ranking is on
The re-ranker runs on your CPU: expect about 10 s a question and 2.3 GB more RAM, so answers will feel slow.
Re-ranking is on
The re-ranker runs through your LLM at your provider, which costs a small amount per question. It has not been benchmarked yet.

7.8Add the website widget#

  1. Open Website widget and choose New widget key. Name it, and list the sites allowed to use it, one address each (for example https://shree-labs.in; plain http:// is accepted only for localhost and 127.0.0.1). Set the messages per minute for each visitor and per day, and the title, greeting, colour and corner.
  2. Copy the embed snippet and paste it into the website before the closing </body> tag:
HTML
<script src="http://127.0.0.1:8000/widget.js" data-key="pk_..." async></script>

Optional attributes are data-open="true" (open the chat on load), data-position="left" and data-color="#0f766e". The pk_ key is meant to be visible in page source: it can only chat with its one knowledge base, only from the sites you listed, and only within the limits you set. The chat panel always shows a small “cob-rag-engine by Callobuzz” link; no setting hides it.

To see it before touching a real site, choose Preview and style on the key. That shows the real widget on a sample website, at phone or desktop width, served from the dashboard at /widget-demo.html. For a live site, set RAG_PUBLIC_URL to your engine’s public HTTPS address so the snippet points there.

The widget answers with the same model as the playground, so it needs the AI model key you skipped (see the playground step) before visitors get answers.

7.9Invite a teammate#

In the customer’s dashboard open Team and choose Invite teammate. They can be an Owner or a Member. The invitation link is valid for 7 days and works once. With no SMTP the invitation e-mail is in the mailer’s log.The invitation is sent by e-mail. Members can use the playground, view everything, upload content and edit prompts and retrieval settings. Owners can also create or delete knowledge bases, manage API and widget keys, set the model key, and manage the team.

7.10Plans and limits#

Open Plans as operator. A fresh install has one plan, Standard, with no limits. A plan can cap four things, each optional: knowledge bases, questions per month, active documents and website widget keys. Move a customer between plans from Customers, then Change plan. Customers see their own usage against the caps under Plan & usage, and you see metered usage per customer under Usage. What the models really cost you is under Costs: the provider’s own figure for every answer, by customer, knowledge base, model and source, with a CSV export. A price the engine cannot find reads “price unknown”, never ₹0.00, and the header shows this month’s spend (and your OpenRouter balance when that is your provider). Payments are not built in: the usage meter is what you bill from.

7.11Set up the assistant#

Every knowledge base already has an assistant, switched on. This is how its owner makes it theirs. Changes go into a draft; visitors see nothing until you publish.

  1. Open the knowledge base, then the Assistant tab. Choose Start from a template (for Shree Labs, Clinic or lab front desk) and keep your business name and contacts.
  2. Under Identity fill in the name, what the business does and the business card: opening hours, phone, WhatsApp, e-mail and address. The assistant quotes these exactly, and visitors can ask about them after you publish. Save the draft.
  3. Open Preview and ask three questions the way a visitor would: one the documents answer, one in Hinglish (for example “Lipid profile ka rate kya hai?”) and one it should not answer. Owners see how each answer was made: the passages, the search confidence against its minimum, the facts that were checked and removed, and the instructions sent to the model. Preview questions count as real questions.
  4. Choose Publish (owners only; members can edit the draft). Under Versions you can view any earlier version and restore it as a new live version.
  5. Open the website where the widget is installed and ask the same three questions. If the widget is not installed yet, see Add the website widget.

To get plain grounded answers with no greetings, topic limits, lead forms or hand-off, owners can switch the assistant off on the overview; the old Prompt settings then drive the answers again. Answers show as formatted text: lists, tables, links and source chips.

7.12Leads, handoff and the daily digest#

This is what happens after the assistant has done its job: a visitor wants to be contacted, or needs a person. Everything below is set in the knowledge base’s Assistant tab and saved into the draft, so visitors see it only after you publish.

  1. Open Leads. Keep the mobile number required, add the notification e-mail addresses, and choose when the form is offered (a buying question, no answer found, a person asked for, out of hours). Leads are stored encrypted, so the engine needs RAG_ENCRYPTION_KEY; without it the assistant publishes with leads switched off.
  2. Under Qualifying leads choose Add a rule: for example Qualified when why they left their details is equal to asked about buying, and a second rule marking Partly qualified when the name is given. A lead that matches neither is marked unqualified; with no rules nothing is marked and nothing changes. A qualified lead’s thank-you shows a Book now button when the business card has a booking page. The inbox on the Leads page filters by it.
  3. Tick Daily digest under Notify if you would rather not get a mail for every unqualified lead. Those leads then arrive in one mail a day, listing yesterday’s leads, sent at RAG_LEAD_DIGEST_HOUR (9 by default) in the business time zone from the business card. An empty day sends nothing. Qualified and partly qualified leads are still mailed at once.
  4. Under Talk to a person choose the ways to reach the business (WhatsApp, call, e-mail, a call-back request) and the office hours. When a visitor needs a person the assistant offers them; you see who was offered one on the Handoffs tab of the Leads page, and can mark each one handled.
  5. Under Conversation add a proactive greeting, for example the page /tests/**, a delay of 10 seconds and the message “Need help choosing a test?”. In a page address * stays inside one part and ** goes across /. It shows once per visit, never over an open chat, and the visitor can choose “Don’t show again”.
  6. Under Guidance rules, press Improve next to a rule you wrote in a hurry. It suggests a clearer wording and names the rules it may clash with; nothing changes until you press Use this wording, and you still save the draft yourself. It uses the knowledge base’s own model, so it needs one set up.
Contact data in e-mail
The new-lead mail and the digest carry names and phone numbers through the engine’s queue for up to six hours before they are sent. Use an SMTP server you trust, and keep the consent notice and your own privacy policy up to date: the engine’s defaults are a starting point, not legal advice.

Back to top

08Connect an AI agent (MCP)#

cob-rag-mcp is a companion MCP server and command-line tool that plugs a knowledge base into Claude, Cursor, VS Code, n8n or any MCP client. It is only a client: it talks to the engine you just started, and nothing is sent anywhere else. You need Node.js 22 or newer.

8.1What it needs#

The engine address (http://127.0.0.1:8000 here) and a key. Use a key of the knowledge base itself (it starts with ck_), which lets the agent see that one knowledge base and nothing else. Give every agent its own named key with the lowest permission it needs: read searches, asks and lists; write also adds and changes content; full also deletes and manages keys. Revoking one key cuts that agent off and touches nothing else. The server asks the engine who the key is and offers only the tools that key may use. Destructive tools stay hidden unless you set COB_RAG_ALLOW_DESTRUCTIVE=true, and deleting a knowledge base or a document always needs the item’s exact name (confirm_name).

The easy way: open the dashboard’s Agents (MCP) page, choose your client under Connect an agent, leave the permission on Read and press Create key and show config. It makes a key named “Agent – <client>” and shows the exact config for that client with the key already in it. The key is shown once, so copy the config before you leave the page.

8.2Claude Code#

Git Bash
claude mcp add cob-rag \
  -e COB_RAG_URL=http://127.0.0.1:8000 \
  -e COB_RAG_API_KEY=ck_your_corpus_key \
  -- npx -y cob-rag-mcp start
PowerShell
claude mcp add cob-rag -e COB_RAG_URL=http://127.0.0.1:8000 -e COB_RAG_API_KEY=ck_your_corpus_key -- npx -y cob-rag-mcp start
Terminal
claude mcp add cob-rag \
  -e COB_RAG_URL=http://127.0.0.1:8000 \
  -e COB_RAG_API_KEY=ck_your_corpus_key \
  -- npx -y cob-rag-mcp start

8.3Claude Desktop and everything else#

For Claude Desktop, add this to claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\) and restart it:

claude_desktop_config.json
{
  "mcpServers": {
    "cob-rag": {
      "command": "npx",
      "args": ["-y", "cob-rag-mcp", "start"],
      "env": {
        "COB_RAG_URL": "http://127.0.0.1:8000",
        "COB_RAG_API_KEY": "ck_your_corpus_key"
      }
    }
  }
}

Cursor, VS Code, n8n, the streamable HTTP mode and the cob-rag-engine command-line tool are covered in the cob-rag-mcp README and on its website; the package is on npm. The dashboard’s Agents (MCP) page links there too.

8.4Install before npm publish#

Until the package is published on npm, npx -y cob-rag-mcp start does not work. Install it from a checkout instead (Node.js 22 or newer and pnpm):

Terminal
git clone https://github.com/callobuzz/cob-rag-mcp.git
cd cob-rag-mcp
pnpm install && pnpm build && npm link

npm link puts the cob-rag-mcp command on your PATH. Then use it wherever a config above says npx -y cob-rag-mcp start: the command is cob-rag-mcp and the arguments are start. For Claude Code:

Terminal
claude mcp add cob-rag \
  -e COB_RAG_URL=http://127.0.0.1:8000 \
  -e COB_RAG_API_KEY=ck_your_corpus_key \
  -- cob-rag-mcp start

The environment variables are the same either way: COB_RAG_URL, COB_RAG_API_KEY and, for a customer (tk_) key, COB_RAG_CORPUS_ID, the knowledge base the tools default to. The dashboard’s Connect an agent shows these local-install commands until the package is on npm.

Back to top

09Day-to-day#

Run these from the repository folder. Each has a make shortcut where one exists.

Leads that visitors leave in the website widget appear under Leads in the dashboard. A lead is new until someone follows up, then contacted, and ends as won, lost or spam. Owners can export the list as a CSV and delete a lead; members can update status, assignee and notes. A visitor can withdraw consent from the link shown after they submit, which deletes their details. Put your own purpose, contact and privacy policy link in the consent notice (Assistant, Leads): the defaults are a starting point, not legal advice. Set RAG_PUBLIC_URL so withdrawal links use your public address.

When a visitor asks for a person, the widget offers the ways to reach you (WhatsApp, a call, e-mail, a booking link or a call-back request), chosen by the office hours on your business card. A tap is recorded as a handoff: it appears in the Handoffs tab beside Leads, with a short summary and the chat, and is e-mailed to you (and sent to your knowledge base’s webhook as handoff.requested). Open one and press Mark handled when you have followed up; members can do this too. WhatsApp links open a chat on the visitor’s phone with their question already typed; nothing is sent until they press send. There is no live takeover: the assistant keeps answering.

Every week, open Review in the dashboard (or GET /assistant/review) and fix what visitors could not get answered with one click. Before a big change, run your golden set as an experiment and compare it with the last run. Quick checks, your own criteria and comparisons need nothing extra. Scoring answers with the RAGAS metrics (faithfulness, answer relevancy, context precision and recall) and the operator’s traffic evaluations and optimisation runs need the optional evaluation add-on, which brings LangChain: set RAG_INSTALL_EVAL=true in .env and run docker compose build (the wizard asks), or pip install 'cob-rag-engine[eval]' for a native install. Without it the Quality page says so and keeps everything else working.

Stuck on a screen? Press the COB button at the bottom right of the dashboard, or Ctrl+/ (⌘+/ on a Mac). COB is the engine’s own assistant: it answers from this engine’s help pages in English, Hindi or Hinglish, shows which pages it used, and opens the right screen for you. The panel can be resized, takes the whole screen on a phone, and keeps your chats private for 30 days (delete any time). A COB answer counts toward your workspace’s monthly questions; once they are used up it shows matching help pages instead of writing an answer.

Prefer to read? Open Docs in the dashboard menu. It holds the guides, the help page of every screen and the API reference, with search (press /), a contents list on each page and examples that already show your engine’s address. The small ? beside a screen’s title opens that screen’s page, and Ask COB about this page hands the page to COB. You see the pages for your role; the server and operations pages are for the platform operator.

9.1See what is running and read logs#

Terminal
docker compose ps
docker compose logs -f --tail=100 app
# every service at once:
docker compose logs -f --tail=100

The services are app, worker, mailer, celery-beat, scraper, dashboard, postgres, valkey, qdrant and tei. make ps and make logs are the shortcuts. Your setup also runs whisper. Langfuse adds langfuse and langfuse-postgres. You do not use TEI, so there is no tei service.

With no SMTP the mailer’s log is where every sign-up code, activation e-mail, invitation and password reset lands, so this is the log you will read most:

Terminal
docker compose logs -f --tail=100 mailer

With SMTP, docker compose logs mailer shows delivery errors when an e-mail does not arrive.

9.2Restart one service#

Terminal
docker compose restart app

A restart does not re-read .env. After you edit .env, run the start command again (docker compose up -d); Compose recreates only the services whose settings changed. Keep the GPU overlay in the command: without it Compose recreates the services with no GPU. For the dashboard alone: docker compose up -d dashboard.

9.3Stop and start again without losing data#

Terminal
docker compose down

This stops and removes the containers but keeps every named volume: the database, vectors, uploaded files and model cache. make down does the same. Start again with the same command you used the first time (docker compose up -d; add --build only after an update). The containers also come back on their own when Docker starts, because they are set to restart unless stopped.

9.4Update to a new version#

  1. Read CHANGELOG.md in the repository for the release you are moving to. It lists upgrade notes.
  2. Fetch the new code: git pull.
  3. Re-run the wizard so new settings are added and your values are kept (see running it again later).
  4. Rebuild and restart:
Terminal
git pull
python scripts/setup.py
docker compose up -d --build

Database migrations run automatically: the app’s entrypoint runs alembic upgrade head before it starts serving, and stops with “ERROR: Alembic migration failed!” in docker compose logs app if one fails. On macOS and Linux write python3 for python, and add the GPU overlay to the last command if you use one.

If your install already holds documents and you are updating to the release with named keys, the fast model and page-furniture stripping, run two one-off commands afterwards. Neither re-embeds anything, and each only changes data when you add --apply:

Terminal
docker compose exec app python -m callobuzz_rag.retrieval.reindex --payload-hash --apply
docker compose exec app python -m callobuzz_rag.retrieval.reindex --rehash-blocks --apply

--payload-hash gives chunks stored earlier the fingerprint that lets search show a passage held by several documents once. --rehash-blocks counts the page furniture (menus, footers, cookie notices) already stored, so new pages of the same site are stripped of it. Keys issued before this release keep working: each became its owner’s “Default key” with full permission. The wizard also carries the old RAG_WIDGET_TRUST_PROXY_HEADERS to RAG_TRUST_PROXY_HEADERS and suggests a fast model when you pick a provider. Behind a proxy of your own, also set RAG_TRUSTED_PROXY_HOPS to the number of proxies in front of the engine (see the deploy guide).

If your documents are in Hindi or another Indic language (Devanagari, Bengali, Tamil, Telugu, Gujarati, Kannada, Malayalam, Gurmukhi, Odia), also rebuild the keyword vectors once, because earlier versions indexed those words in fragments. It re-embeds nothing:

Terminal
docker compose exec app python -m callobuzz_rag.retrieval.reindex --apply
Warning
Some updates change what Docker creates. For example, the compose project was renamed to cob-rag, and an install from before that rename starts with new, empty volumes. Always read the changelog first.

Back to top

10Set up billing in 5 minutes#

Billing is optional and quiet until you price a plan. With no price on a plan, nothing is charged and nobody is paused, so you can ignore this section and your customers are limited by their plan only. Everything below is done in the dashboard under Billing (you need the super-admin sign-in). Amounts are whole paise or cents behind the scenes, so totals never drift.

10.1Pick a recipe#

Open Billing, then Pricing, choose a plan and press Edit pricing. The three common set-ups:

  1. Subscription, own key free. Set the Subscription fee (for example ₹999 a month), leave Usage on your AI key on Included, set Usage on their own AI key to Free, and keep the plan’s question limits unlimited. Choose Postpaid with a credit limit at least as large as the fee, so a customer is never paused for the fee itself. Customers who bring their own AI key pay you only the fee.
  2. Pay per question. Choose Prepaid, set A price per question (for example ₹2), and set the Alerts (20, 5 and 0 percent by default). A customer tops up, each answer takes its price from the balance, and answers pause politely at zero.
  3. Real AI cost plus a markup. Choose AI cost plus a markup and enter the markup percentage (25 means 25 percent on top). Each answer is charged what the AI really cost you, converted to rupees at the fixed rate RAG_USD_INR_RATE. The rate is written on the charge, so a charge can always be explained later, even after you change the rate. A call with no known price is charged ₹0 and flagged “price unknown” on the statement. Customers never see the markup.

Press Save pricing. Every save is a new version with a history, and it applies to the next answer. For one customer who deserves a different deal, open their Billing tab, turn on Custom for just the fields you want to change, and press Save terms. Your own workspace and the Internal plan are never billed.

10.2Top-ups, refunds and add-ons#

Payments are recorded by hand for now. When a customer pays you (or asks through Request top-up on their Plan & billing page, which e-mails you), open their Billing tab and press Add a transaction:

  • Top-up adds money to the balance. A large amount must be typed a second time to confirm it.
  • Refund takes money back out. It is limited to what the customer actually paid and still has, and needs a private note.
  • Adjustment corrects a mistake, up or down, with a private note. Nothing in the transaction list is ever edited or deleted; every correction is a new line.

Add-ons are extras you sell: credit packs (money plus an optional bonus), extra limits (more knowledge bases, documents or widget keys) and extra questions for the month. Create them under Billing, Add-ons, then press Apply an add-on on the customer’s tab and say how it was paid: outside the engine, free, or taken from their balance. Pressing a button twice never applies it twice.

10.3What visitors see when a balance runs out#

A prepaid customer pauses when what they can still spend reaches zero (less their grace amount); a postpaid one when they owe their credit limit. The owner is e-mailed at each alert level and again when answers pause, and so are you. Visitors never see the word billing: the assistant still greets them and answers the fixed topics, and any other question gets the knowledge base’s message when answers are paused with its contact card, so nobody is lost. The pause costs you nothing, because no AI model is called. Adding money lifts it within a minute. Pause override on a customer lets you force a pause or never pause.

10.4Statements, the P&L and provider balances#

Every customer gets a statement for each calendar month: opening balance, subscription, usage by knowledge base, model and source, top-ups and the closing balance, which always adds up to the transactions to the last paisa. Customers open it themselves (View, CSV, Download PDF); it never shows your markup or AI cost. Billing, P&L compares what each customer was billed and paid with what your AI key cost you (an estimate), month by month, with the margin. On Costs, Provider balances shows what OpenRouter, OpenAI, Anthropic and any manual provider have left so you know when to top up your own keys. Every night the engine checks that each balance equals its transactions and that every answer was charged once; Books check shows the result and Check now runs it on demand.

10.5What is not built yet#

Good to know
There is no payment gateway yet: no card or UPI checkout, so money is recorded by you after it arrives. Reselling to agencies with sub-accounts is not built either.

Back to top

11Businesses: the simple dashboard and website learning#

A business owner such as a clinic in Pune should never have to learn what a knowledge base or an embedding is. This section covers what you set up as the person who runs the platform, what the owner then sees, and what to check when their website is not read the way they expect.

11.1Choose what businesses see#

Each plan decides how much of the dashboard a business gets. Open Plans, edit a plan and use What businesses on this plan see. The default shows everything, so existing plans do not change until you switch something off. A plain business plan usually turns off Advanced settings: its owners then see only Home, Conversations & Leads, Knowledge, Assistant, Plan & billing, Team and Help. A part you hide is missing from the menu, and the engine refuses its settings for that business’s owners and members, so a bookmark does not get around it. API keys, your own workspace and the admin sign-in are never limited by these switches, and documents, leads, conversations and usage are always available.

The same editor sets Website learning: whether businesses on the plan may let their assistant read their website, and Pages we read from their website. When a website has more pages than the limit, the important ones (home page, menu, prices, services, contact) are read first and the rest show as “Beyond your plan’s page limit”.

11.2What the business owner does#

  1. Sign up and sign in. The first time, four short steps open by themselves.
  2. Step 1, your website. The owner types shreedental.in, names the assistant (for example “Shree Dental Assistant”), chooses its picture, and presses Continue. The knowledge base, the assistant, the website code and the reading of the website are all set up in one go.
  3. Step 2, brochures and price lists. Optional. The owner drops in the files customers ask about, such as a price list or a menu, and sees how many the assistant has read. Skip this step leaves it for later.
  4. Step 3, add it to your website. The owner copies the code, or presses Send to my developer. A light turns green with Connected the moment the assistant loads on the website.
  5. Step 4, try your assistant. The owner chats with it, with suggested questions taken from their own pages. Until the pages are read, the assistant tells visitors politely that it is still learning and shows how to reach the team.

Afterwards the owner works in Knowledge (what was learned and why a page was skipped, plus their own articles and answers) and Assistant (name, picture, tone, languages). The assistant carries the business’s own name and picture; the visitor sees the business, not your product. COB, the built-in helper, is always called COB.

11.3Keeping the website knowledge fresh#

A learned page is checked on a schedule the owner picks (every day by default). A page is read again only when it has changed, so frequent checks cost nothing extra. Three things make it faster than the schedule:

  • The update link. In Knowledge, Update instantly when you publish makes a link the website can call when it publishes a page. Developers on WordPress or any other system can call it from a plugin or a hook. The link is shown once.
  • The widget. The widget on the website notices when a page’s text changed and asks the engine to check that page. It sends only a short code, never the text and never anything a visitor typed.
  • Removed pages. A page that is gone from the website is forgotten after two checks an hour apart. A temporary outage changes nothing.

11.4The light never turns green#

Symptom
Step 3 keeps showing Waiting for your website.
Why
The code is not on the page that was opened, the website was not published after pasting it, or the site is open in an editor preview.
Fix
Paste the code before the closing </body>, publish the website, then open the live page once. After 15 minutes the setup stops checking and the owner can finish later from Home.

11.5www and the plain address do not match#

Symptom
The light says the assistant loaded on www.shreedental.in but the owner typed shreedental.in (or the other way round).
Why
Visitors reached the website by another address than the one allowed.
Fix
Both forms are allowed at setup. If another address appears, press Allow next to it and reload the website.

11.6Google Sites#

Symptom
The assistant loads, but the address shown is a Google address.
Why
Google Sites shows the chat inside a box served from a Google domain.
Fix
Allow the address the setup shows. The pages of the Google Site itself are read from the owner’s own web address when it has one.

11.7robots.txt blocks the bot#

Symptom
Every page shows Asked search engines not to read it, or the website is marked as unreadable.
Why
The website’s robots.txt or page settings ask programs not to read it. The engine obeys them.
Fix
Ask whoever looks after the website to allow reading, or add the owner’s important pages to the assistant as articles in Knowledge.

11.8A website that needs a browser#

Symptom
Pages show Needs a browser to read and few or no pages are learned.
Why
The text is built only inside a browser (a single-page app), so a plain read finds almost nothing.
Fix
If you run the web scraper with browser reading switched on, these pages are read through it. Otherwise the owner can write the key pages as articles and question-and-answer entries.

12Answer speed and fair use#

Two things keep a shared engine fair and affordable. Answer speed decides how each plan’s questions are answered: which AI model, how deeply it searches and who goes first when the engine is busy. Fair use sets how much one business may use and what happens when it passes a limit or its balance runs out. Both are per plan, with an override for a single business, and every default is only a starting point. You need the super-admin sign-in.

12.1Choose a pipeline profile for each plan#

Open Engine, then Pipeline profiles. Three are built in and editable: Economy (the Free profile: the free model on this server, short answers, low priority), Standard (the default: nothing changes until you edit it) and Premium (re-ranking with a model, high priority). Clone one, or press New profile. Every field you leave empty follows the engine, and the help beside it says what that is now. Then open Plans, edit a plan and pick its profile under Answer speed. To give one business a different profile, open Customers, choose the business and open Answer speed & limits.

12.2Set the limits#

  1. Open Plans, edit a plan and scroll to Fair use.
  2. Fill only the limits you want: questions a minute, an hour and a day, answers at once, website pages and reads, files, storage, AI spend (in dollars) and questions to COB. Empty means no limit.
  3. Under What happens, choose what the engine does when the balance runs out and when a limit is passed. The defaults keep answering on the free, slower profile and pause politely only far past a limit.
  4. For one business, open its Answer speed & limits tab and choose Follow plan, Own limit or No limit for each limit.

The seeded Free plan starts at 30 questions an hour, 300 a day and 50 website reads a day. Edit it to suit your product.

12.3What happens past a limit or an empty balance#

  • Near a limit (80% by default): nothing changes. The owner sees a notice and gets an e-mail, and so do you.
  • Past a limit: answers continue on the free profile, slower, until the limit resets. With Hard stop they pause at once; with Only tell me nothing slows down.
  • Far past a limit (150% by default): visitors see the business’s own pause message and contact options.
  • Balance runs out: answers continue on the free profile at no charge, or pause, or carry on as usual, as the plan says.
  • The AI spend ceiling stops at the ceiling exactly. Answers move to the free local model when it is ready, and pause when it is not.

A visitor never sees an error and the website widget never mentions a plan, a limit or a balance. Your own workspace, the Internal plan and the admin sign-in are never limited.

12.4Turn on the free local model#

Slowing down for free needs a model that costs you nothing: a small open model that runs on this server’s CPU. It needs about 6 GB of free memory.

  1. Run python scripts/setup.py --full and answer yes to free answers on this server (or set RAG_LOCAL_LLM_ENABLED=true and add local-llm to COMPOSE_PROFILES).
  2. Run docker compose up -d. The first start downloads the model.
  3. Open Engine. The Free local model card says “Downloading the model”, then “Ready”. Press Try it to hear how fast it answers.

Until it says Ready, a business that would be slowed down is paused politely instead, never shown an error. Safety rails and Answers right now on the same page set an engine-wide AI spend ceiling and show what is being answered.

12.5What owners see#

An owner sees a banner in your product’s name when a limit is near, passed or reached, a Fair use card on Plan & billing with a meter for each limit, and a tile on Home. AI usage is shown only as a share, never as an amount of money. A member reads the same words. COB can explain all of it: ask “Why have my answers become slow?”.

Back to top

13Trust and value#

The engine is built so a visitor is never stuck or misled and an owner is never surprised, and so a business can see what its assistant is worth. Every default is the safe, customer-friendly one. You change the switches under Sign-up & branding (the trust engine settings); owners change only what is their own choice.

13.1A person, always#

A visitor who asks for a person (“talk to a person”, “insaan se baat karni hai”) gets the business’s contact options on the first ask, in every state: balance empty, website still being learned, monthly limit reached, fair-use limits, busy engine. Asking is free and is not counted as a question. Every chat header has a Talk to a person button; you decide whether an owner may hide it (Let businesses hide the Talk to a person button, off by default). The assistant also offers a person after an unanswered question (the owner can change this from 1 to 5, or never) and never gives the same reply twice in a row.

13.2Nobody repeats themselves#

A chat that is offered a person gets a short reference such as SD-4F7K. The WhatsApp message opens with it and the visitor’s last few questions, the call option shows it, and the owner’s e-mail, the leads export and the data sent to the business’s own systems carry it. Owners find a chat by typing the reference on the Handoffs tab of Leads. Phone numbers and e-mail addresses are hidden in the summary unless the visitor left their details.

13.3No surprises#

The plan page shows the next renewal with its exact amount and a projection of the month; owners are e-mailed before each renewal (7 days by default). A price rise is announced at least 30 days ahead (7 to 90, your choice), is scheduled in Billing, and applies to each business only from its next period. Owners set a monthly spending cap, up to a maximum you choose; at the cap the assistant switches to a slower model or pauses, and a visitor who asks for a person is never refused. Businesses write a support request from Get help, you answer it in the Support inbox, and you can show how fast you usually reply. The Price list page makes a white-label list of your plans to print or share by a link you can turn off.

13.4The value report#

Every month the owner gets an estimated value in rupees, always shown with its formula and always “based on your settings”: qualified leads, requests to talk to a person and staff time saved, each times a number the owner sets. It is on Home, in a full report with a print page and in an e-mail on the 1st. You can switch it off for everyone or copy your support address on every e-mail.

13.5Honest about being an AI#

Every chat shows an AI assistant badge next to the assistant’s name and starts with a line saying so, in the visitor’s language. By default you require both, so no owner can switch them off (Always show the AI badge and first line). Let businesses word the first line lets an owner use their own wording as long as it still says AI; anything else shows the standard line. Turn the first switch off only if your businesses must be free to hide it.

13.6How fresh an answer is#

The assistant knows when each source last changed and says so: the source chips show “Updated 3 Oct”, and a visitor can ask when something was updated. The date is the day the text of the page or file last changed, in the business’s time zone, so a page that is read again with no change keeps its date. The owner sees the same date in the Changed column of Knowledge. Home also suggests adding brochures and price lists while an assistant has no files and has read only a few pages, and the first-run steps ask for them as step 2.

14WhatsApp#

WhatsApp is one more place where a business’s assistant answers. A customer writes to the business’s own WhatsApp Business number and the same assistant that answers on the website replies, from the same knowledge, behind the same gates (a request for a person, the monthly limit, the balance, fair use). Each platform operator registers their own Meta app: the engine ships with none, and until you switch it on (RAG_WHATSAPP_ENABLED) nothing about it appears in the dashboard.

14.1Your Meta app#

In Meta for Developers create a Business app with the WhatsApp product and note its App ID and App Secret. Verify your business (Business Verification). To let businesses sign in with Facebook (Embedded Signup version 4), become a Tech Provider and pass App Review for whatsapp_business_management and whatsapp_business_messaging; Meta lets a new provider onboard about 10 numbers a week at first and raises it to 200 a week later. Before that, connect numbers by hand. The full steps, the webhook address and the settings are in the deployment guide, section Connect WhatsApp (Meta app).

14.2Connecting a number#

A workspace owner opens WhatsApp in the menu and chooses Connect with Meta: Facebook’s window opens, the owner picks the business and the number, and the engine registers it (with a PIN it derives from the number, so a retry always uses the same one), subscribes your app to its messages and stores the token encrypted. A number that is also in the WhatsApp Business app is already registered and is left alone. Or you connect it for them: Customers, the customer, Knowledge bases, Connect WhatsApp for this business, then paste the phone number ID, the WhatsApp Business Account ID and a permanent token. To have the engine register the number, also type a six-digit two-step PIN; leave it empty if you already registered the number in Meta’s dashboard. A number belongs to one knowledge base at a time. Disconnecting keeps the chats, and it stops Meta’s message subscription only when no other connected number uses the same WhatsApp Business Account. Connecting a different number to the same knowledge base starts its chats fresh: earlier STOP and opt-in choices do not carry over.

14.3Plans and Meta’s fees#

Tick WhatsApp included on each plan that should have it: the menu item and the routes then appear for those businesses only, and the operator’s own view is unaffected. Meta charges for some messages. A business that connects its own WhatsApp Business account pays Meta directly. For a number on your account, choose per plan whether the fees are passed on or included, and under Sign-up & branding enter your rate per category (service, utility, marketing, authentication) in paise or cents. Every rate starts at zero and the engine states no prices: use Meta’s current price list for your country. A fee is charged once per message and shows as WhatsApp on the business’s statement.

14.4What owners see#

The WhatsApp page lists the chats (names partly hidden), shows unread ones and lets the owner or a member reply inside WhatsApp’s 24-hour window. A reply makes the assistant stay quiet in that chat for the hours the owner sets (12 by default); a reply from the WhatsApp Business app on the same number does the same when coexistence is on. A customer who writes STOP is never messaged first again, and the one optional follow-up (an approved template, off by default) is never sent to them. The assistant can send brochures, price lists and menus, but only from the PDFs, JPGs and PNGs the owner ticks, up to 20.

Back to top

15Tear down and reset#

15.1down versus down -v#

docker compose down stops the stack and keeps your data. docker compose down -v also deletes the volumes.

This deletes data
docker compose down -v permanently deletes the database, vector store, uploaded files, Valkey data and model cache: every customer, knowledge base, document and account on this install. There is no undo. Use it only when you want to start from nothing. (make clean runs the same down -v and also removes Python cache folders.)
Terminal
docker compose down -v

15.2Remove the images too#

The images take disk space. This stops the stack, deletes the volumes and removes the images Compose used (Docker skips any image another project still uses):

Terminal
docker compose down -v --rmi all

15.3Start completely fresh#

  1. Delete the data: docker compose down -v.
  2. Move the old settings aside. The wizard keeps the values it finds, so to get brand-new secrets the file has to be gone:
Git Bash
mv .env .env.old
PowerShell
Rename-Item .env .env.old
Terminal
mv .env .env.old

Then run the wizard again (step 4) and start the stack (step 5).

Warning
Delete the volumes whenever you replace .env. PostgreSQL only reads its password when its volume is first created, so new secrets with the old volume leave the app unable to sign in to the database. To reset the data but keep your settings, leave .env in place.

Back to top

16Troubleshooting#

Each item reads symptom, why it happens, fix. The ones that match your setup come first. Start with docker compose ps and docker compose logs <service>; they answer most questions.

16.1Port already in use#

Symptom
docker compose up fails with a message like “port is already allocated” or “address already in use”.
Why
Another program on your machine already uses one of the ports (8000, 8001, 8090, or a datastore port such as 5433 or 6380).
Fix
Find it, then free it or move the stack. To see who holds a port (8000 here):
Git Bash
netstat -ano | findstr :8000
PowerShell
netstat -ano | findstr :8000
Terminal
lsof -i :8000
To move the three web ports, re-run the wizard with --full (it asks for the host ports and updates the matching addresses and allowed origins), or pass one directly:
Terminal
python scripts/setup.py --quick --yes --gpu no --set "RAG_APP_HOST_PORT=8100"
Then run the start command again. The datastore, TEI and Qdrant ports are fixed in docker-compose.yml; stop whatever uses them instead.

16.2Docker Desktop is not running#

Symptom
Every docker command fails with “Cannot connect to the Docker daemon” or, on Windows, a pipe error such as “The system cannot find the file specified”.
Why
The Docker engine is not started. Docker Desktop has to be open (or the Docker service running on Linux) before any compose command works.
Fix
Start Docker Desktop and wait until it says the engine is running.Start the service with sudo systemctl start docker. Check with docker info, then run the start command again.

16.3Containers are unhealthy or restarting#

Symptom
docker compose ps shows unhealthy, Restarting or Exited for a service.
Why
Something the service needs is missing or wrong. The last lines of its log almost always say what.
Fix
Read the log of that service, newest lines last:
Terminal
docker compose logs --tail=100 app
Replace app with the service name. Causes the wizard itself warns about: RAG_SMTP_HOST set but RAG_SMTP_FROM empty (the engine will not start); RAG_ENV=prod with RAG_EMAIL_PROVIDER=log (refused); RAG_EMBEDDING_PROVIDER=tei without tei in COMPOSE_PROFILES (ingestion fails). A line such as “set RAG_DB_PASSWORD in .env” means a required secret is empty: re-run the wizard. A failed migration shows “ERROR: Alembic migration failed!” in the app log. After fixing .env run docker compose up -d.

16.4The first start is very slow#

Symptom
docker compose ps shows tei as starting for minutes, and the app does not become healthy.
Why
The embedding container downloads its model (BAAI/bge-base-en-v1.5) on first start, and the images are being built. This is normal.
Fix
Wait, and watch docker compose logs -f tei. The compose file allows TEI 120 seconds before the first health check and then 30 checks ten seconds apart. The download is cached in a Docker volume, so the next start is fast. If you chose a local re-ranker or in-engine embeddings, those models download too.

16.5The GPU is not used#

Symptom
Embeddings or the re-ranker run slowly, the TEI log does not say it is starting the model on Cuda, or Compose refuses to start a service with “could not select device driver nvidia”.
Why
Compose refuses to start a service that reserves a GPU the host does not have, which is why the GPU overlay is never the default. The TEI container also needs the CUDA image, not the CPU one. On Docker Desktop for Windows, TEI’s CUDA image cannot see the GPU.
Fix
Run the GPU check from step 2. If it fails, answer “no” (python scripts/setup.py --gpu no) and use the plain start command. If it works, answer yes and use the GPU start command. On Windows, quick mode picks the engine’s own embeddings for you, which use your GPU without TEI. For TEI on Linux with a specific card you can set RAG_TEI_IMAGE to the tag for its generation: turing-1.9, 86-1.9 (Ampere), 89-1.9 (Ada), hopper-1.9, 120-1.9 (Blackwell) or the portable cuda-1.9, all under ghcr.io/huggingface/text-embeddings-inference. The local re-ranker alone needs about 2.3 GB of GPU memory.

16.6localhost does not work on Windows#

Symptom
http://localhost:8090 resets or never loads, but the containers are healthy.
Why
On Windows with Docker Desktop, localhost resolves to the IPv6 address ::1 first, and Docker Desktop resets that connection. It looks exactly like the service being down.
Fix
Use http://127.0.0.1:8090 (and 127.0.0.1 in every address you put in .env).

16.7The dashboard cannot reach the engine#

Symptom
The dashboard loads but shows a network or connection error, or every call fails in the browser.
Why
Your browser calls the engine and the scraper directly. Two settings must match the address you actually use: RAG_DASHBOARD_ENGINE_URL and RAG_DASHBOARD_SCRAPER_URL (where the browser reaches them), and RAG_CORS_ORIGINS (which must list the dashboard’s own origin; the scraper has SCRAPER_CORS_ORIGINS). They break when you change a port, open the dashboard from another address, or put the stack behind a domain. The dashboard’s Content-Security-Policy only allows calls to the two configured addresses.
Fix
First check the engine itself: http://127.0.0.1:8000/api/v1/health should answer. Then run python scripts/setup.py --full and set the “Web addresses” (it merges the dashboard’s origin into both CORS lists), and recreate the services with docker compose up -d. For a live deployment use your public https addresses and follow the deploy guide.
Symptom
You search the logs and find no “ONE-TIME SET-PASSWORD” block, or no e-mail arrived.
Why
The link is only created when RAG_SUPERADMIN_EMAIL is set (otherwise the log says “No RAG_SUPERADMIN_EMAIL; skipping”), and the account needs RAG_SESSION_SECRET, which the wizard generates. With SMTP the link is e-mailed, not printed. Old log lines may also have rotated away.
Fix
Re-run the wizard and enter the e-mail (or --set "RAG_SUPERADMIN_EMAIL=admin@yourcompany.in"), then restart the app with docker compose up -d app. To issue a new link and print it on screen right now:
Terminal
docker compose exec app python -m callobuzz_rag.accounts.bootstrap --resend --print-link
If your password is already set, --resend issues a fresh code anyway.

16.9Sign-up codes do not arrive#

Symptom
A customer signs up but no 6-digit code shows up in their inbox.
Why
You skipped SMTP in the wizard, so nothing is sent: in development (RAG_ENV=dev) every message is written to the mailer’s log instead.The mail server may be refusing the message. Gmail needs an app password, not your normal password, and the message may have landed in spam. In production (RAG_ENV=prod) with no SMTP, e-mail is disabled and sign-up is unavailable.
Fix
Read the code from the log:
Git Bash
docker compose logs mailer | grep -A12 "DEV EMAIL"
PowerShell
docker compose logs mailer | Select-String -Context 0,12 "DEV EMAIL"
Terminal
docker compose logs mailer | grep -A12 "DEV EMAIL"
Check the mailer’s log (docker compose logs mailer) for errors, and use With SMTP set up you would check the same log for errors, and you could use Email (SMTP) in the operator dashboard to check the configuration and send yourself a test. Temporary failures are retried after 15, 30, 60, 120 and 240 seconds, and a message whose code would already have expired is dropped (codes last 10 minutes), so ask for a new code.

16.10“Too many attempts” or a sign-in lockout#

Symptom
The dashboard says “Too many attempts. Try again in …” or “Too many tries. Login is paused for …”.
Why
The engine rate-limits the account routes. Sign-in allows 10 tries per e-mail per 15 minutes and 30 per address per 5 minutes. From the fifth wrong password in 15 minutes the e-mail is locked for 1 minute, doubling each further failure up to 15 minutes, and the lock refuses even the right password. Sign-up allows 5 per hour from one address and 3 per hour for one e-mail. The limits live in Valkey, and if Valkey is down the engine refuses rather than running unlimited (“Sign-in is briefly unavailable”).
Fix
Wait for the time the message gives. A correct sign-in, or finishing a password reset, clears the failure count and the lock. If you see “briefly unavailable”, check docker compose ps redis.

16.11“Workspace not active”#

Symptom
A customer sees “We’ll activate your workspace soon” or “<name> is paused”, or their key gets a 403 workspace_not_active.
Why
The workspace is pending (approval mode, not activated yet) or suspended. Their people can still sign in and see the status page; keys, widgets and agents are refused, and widget visitors see “This assistant is not available right now.”
Fix
As operator, open Customers. Choose Activate on the Pending tab, or Reactivate on the Suspended tab. It takes effect on the next request and nothing was deleted.

16.12A plan limit message#

Symptom
“Monthly question limit reached (412 of 1,000). It resets on …”, or “Your plan allows N knowledge bases / documents / website widget keys.”
Why
The customer’s plan has a cap and they reached it. The month is the calendar month in UTC. Searches that only retrieve passages are not counted, and cached answers do not count. The admin key and super admin are never capped.
Fix
Move the customer to a bigger plan (Customers, then Change plan) or edit the plan under Plans. Lowering a limit never deletes anything; it only blocks new additions. At the question cap, widget visitors see a polite “not available” message and nothing about the plan.

16.13An upload is refused as too large#

Symptom
The upload is refused with “File too large” (HTTP 413, code upload_too_large), or it is accepted and the job later fails with “The document holds N tokens of text; the limit is M” (code document_too_large).
Why
There are two limits. The file itself may be at most RAG_MAX_UPLOAD_BYTES (50 MB by default). And the text inside it, counted after the engine has read the file, may be at most RAG_MAX_DOCUMENT_TOKENS (500,000 tokens by default), so a large scan with little text is fine and a small file with a great deal of text may not be. A plan can set lower limits for one customer, and the dashboard shows the limits that apply to you when you add content.
Fix
Split the document into smaller files, or export its text and import it as records (Add content, then Records import, or POST /api/v1/ingest/records), which takes up to 1,000 records per request and up to 200,000 characters of text in each. To allow more, raise the two settings in .env and restart, or raise the customer’s plan limits.

16.14Answers are slow#

Symptom
The playground or widget takes many seconds to answer.
Why
Most of the time is the language model: a large model, a slow provider, or Ollama running on a CPU. The second common cause is the local re-ranker on a CPU, which the wizard measured at about 10 s a question.
Fix
Choose a faster model (RAG_LLM_MODEL, or per knowledge base in the dashboard). Set a small, quick fast model from the same provider (RAG_LLM_FAST_MODEL): with none, a thinking model rewrites every search question itself, at RAG_LLM_FAST_THINKING (off, or the model’s lowest setting). If your model thinks before it answers, switch Thinking off (RAG_LLM_THINKING=off, or per knowledge base under Model & keys in the dashboard): off is fastest and cheapest, high is more careful. The older RAG_LLM_REASONING_EFFORT still works (none means off). Turn the re-ranker off, or use it on a GPU or through your LLM (the Standard and Premium presets already leave it off on a machine without a GPU unless you switch it on for the whole engine): re-run the wizard and answer the re-ranker question, or change it under the knowledge base’s Retrieval settings.

16.15Answers fail: no AI model key#

Symptom
The playground or the widget cannot answer, while uploading and searching work.
Why
You skipped the AI model in the wizard. Answers are written by a language model, so they need a key; only uploading and searching work without one.
Fix
Set RAG_LLM_API_KEY in .env (the default provider is OpenRouter; for another provider also set RAG_LLM_PROVIDER and RAG_LLM_MODEL, or re-run the wizard and pick one), then recreate the services:
Terminal
docker compose up -d
An owner can also give one knowledge base its own model and key in the dashboard.

16.16I forgot the admin password#

Symptom
You cannot sign in to the dashboard as the super admin.
Why
Passwords are stored as hashes, so nobody can read them back, but there are two ways in.
Fix
Use Forgot password? on the sign-in page. It sends a reset code to your e-mail (with no SMTP, find it in the mailer log as in the sign-up item aboveit arrives by e-mail). Or sign in with the admin key through Use an API key instead (RAG_ADMIN_API_KEY in .env). Or issue a new set-password link with the bootstrap --resend --print-link command from the “no set-password link” item. Finishing a reset also clears any sign-in lockout.

16.17Where is the admin API key?#

Symptom
You need the admin key for the API, the MCP server, or the dashboard’s key sign-in, and you do not remember it.
Why
The wizard generated it and, like every secret, never printed it.
Fix
It is RAG_ADMIN_API_KEY in the .env file in the repository root. Print just that line with the command under First login, the admin key. Send it in an X-API-Key header. Keep it private: it can do everything on the engine.

16.18Back up RAG_ENCRYPTION_KEY#

Symptom
You are moving to a new machine, rebuilding, or worried about losing .env.
Why
RAG_ENCRYPTION_KEY encrypts the LLM keys your customers store in their knowledge bases. Without it those stored keys cannot be read, and every customer would have to paste theirs again. It is generated once and never printed.
Fix
Copy it into a password manager now, apart from the repository. The wizard’s .env.backup-* files and your .env hold all your secrets, so store them as carefully as the key. The engine can rotate the key, and python -m callobuzz_rag.core.reencrypt rewrites stored tokens under the new primary key; see the README’s Operations section.

16.19A file fails: no readable text#

Symptom
A file is uploaded but its job fails with “We couldn’t find readable text in this file. If it’s a scanned PDF, enable OCR or upload a text version.” (code no_text_found). Nothing is added to the knowledge base.
Why
The engine read the file and found no text in it. The usual cause is a scanned PDF or a photo of a page while OCR (reading text from images) is switched off, or a file that is empty or holds only pictures.
Fix
For a scan, set RAG_OCR_ENGINE to rapidocr (the default) or tesseract in .env and restart, then upload it again. For Hindi or another Indian language see 12.20. Otherwise export the text and upload that, or import it as records. A file you were replacing stays exactly as it was.

16.20A scanned Hindi document comes out garbled or empty#

Symptom
A scanned PDF or photo in Hindi (or Marathi, Tamil, Telugu...) is ingested, but its text is missing words, jumbled or Latin-only.
Why
OCR reads English unless you tell it the language, and the default engine (rapidocr) reads Devanagari unreliably: on our test page it recovered about half of the text, while paddleocr recovered 99%. The engine logs a warning at start-up when RAG_OCR_LANGS names an Indian language and RAG_OCR_ENGINE is rapidocr.
Fix
Set RAG_OCR_LANGS=hi,en and RAG_OCR_ENGINE=paddleocr in .env (the first non-English language picks the model; it reads the English words too). PaddleOCR is an optional extra: build the image with docker compose build --build-arg INSTALL_OCR_PADDLE=true, or run pip install -e ".[ocr-paddle]" when you run natively. Restart, then upload the file again. Prefer Tesseract? Set RAG_OCR_ENGINE=tesseract; the image already has the Hindi data (tesseract-ocr-hin), and other languages need their own tesseract-ocr-<code> package added to the Dockerfile. Codes: en, hi, mr, ne, sa, ta, te, kn (paddleocr and rapidocr), plus bn, gu, ml, pa, or, as, ur (tesseract only).

Back to top

17Where to get help#

  • A bug or a question: write to callobuzz@gmail.com.
  • A security problem: do not post it in public. Write to callobuzz@gmail.com with “security” in the subject.
  • Everything else about the engine: the README.md in the repository covers configuration, the API, plans, accounts and operations.
  • The API reference: http://127.0.0.1:8000/docs on your own install (hidden when RAG_ENV=prod), or docs/openapi.json in the repository.
  • Agents and the command line: cob-rag-mcp.
  • Questions before you buy, or help with a first set-up: callobuzz@gmail.com.

Back to top