Files
2026-08-19 17:08:45 +05:30
..
2026-08-19 17:08:45 +05:30
2026-08-19 17:08:45 +05:30
2026-08-19 17:08:45 +05:30
2026-08-19 17:08:45 +05:30
2026-08-19 17:08:45 +05:30
2026-08-19 17:08:45 +05:30
2026-08-19 17:08:45 +05:30
2026-08-19 17:08:45 +05:30
2026-08-19 17:08:45 +05:30

Doormile AI — retrieval sidecar

Semantic intent routing and document Q&A over a local ChromaDB.

This is dev tooling. The production image is still the static nginx build. The console works with this stack absent — the assistant falls back to its deterministic matcher whenever REACT_APP_AI_URL is unset or unreachable.

Run it

docker compose up -d                    # chroma :8000, sidecar :8787
docker compose exec ai-sidecar npm run seed
curl localhost:8787/health

Then point the console at it:

REACT_APP_AI_URL=http://localhost:8787

Leave that unset and nothing changes — the bot behaves exactly as it does today.

What it does

Endpoint Purpose
POST /route which intent is this question? + confidence
POST /ask which documentation passages answer this?
GET /health model + collection counts

What it deliberately does not do

  • No operational data is embedded. No bookings, riders or customers. A vector store is a snapshot; this data changes by the minute. Every figure the operator sees still comes from a live API call.
  • No generation. /ask returns source passages verbatim with attribution. Summarising needs a hosted model — see assistant/CLAUDE.md §2.
  • No key. The embedding model runs in-process. That is what puts this outside §2's blocker.

Evaluation

docker compose exec ai-sidecar npm run eval

Runs the held-out set in eval-set.json — phrasings that appear nowhere in phrasings.json and were not used to tune the thresholds. Retrieval always looks good against its own seed data, so this is the only number worth quoting.

Ship criteria: ≥80% accuracy and zero false write routes.

After changing anything

Re-run npm run seed after editing phrasings.json, any indexed markdown, or the embedding model. Nothing errors if you forget — answers just quietly drift from the source, which is the worst kind of failure to chase.