Skip to content

codebybilal18/documind-web

Repository files navigation

DocuMind Web

Next.js frontend for documind-api — upload documents, ask questions, and read answers whose citations you can click, whose claims have been checked, and whose cost is on screen.

Backend is live at https://documind-api-theta.vercel.app — set NEXT_PUBLIC_API_URL to it.

Live demo: (add your Vercel URL once the frontend is deployed)


What the UI is actually for

Three things are visible here that a typical RAG demo hides, and each is deliberate:

The retrieval panel. Collapsed by default, but present: which passages, at which rank, found by vector search, keyword search, or both, and with what score. "Which retriever found this?" is the first question a reviewer asks about a hybrid-search claim, and a UI that cannot answer it is asking to be taken on faith.

Per-claim verification. Every factual sentence is checked against the passage it cites, and the verdict is shown — supported, partial, unsupported, or unchecked. A model will cite a real passage for a claim that passage never makes; without this panel that is invisible. Flagged claims show by default and the clean ones collapse, so the panel is quiet when there is nothing wrong.

The cost and confidence strip. Tokens in and out, dollars, time to first token, total latency, and a confidence breakdown — not a single percentage. "87% confident" is unactionable; "retrieval strong, two claims uncited" tells the reader which part to distrust.

The config picker on the Chat page lets you ask the same question through benchmark configs A–D and watch the retrieval panel, latency, and cost change. That is the benchmark, made tangible.


Pages

Route What it does
/ Upload PDFs, drive ingestion, list the indexed corpus
/chat Streamed answers with citations, verification, and badges
/evals The benchmark table and the HNSW recall/latency curve, read live from the API

Running locally

cp .env.example .env.local     # point NEXT_PUBLIC_API_URL at your API
npm install
npm run dev

The API must be running and its CORS_ORIGINS must include http://localhost:3000.

npm run build       # production build
npm run typecheck   # tsc --noEmit
npm run lint

Deploying to Vercel

vercel --prod

Set NEXT_PUBLIC_API_URL to the deployed API's URL. It is inlined at build time, so changing it requires a redeploy, not just an environment-variable edit. Add the resulting frontend origin to the API's CORS_ORIGINS — these are two separate Vercel projects and every call between them is cross-origin.


Implementation notes

The SSE client is hand-rolled (lib/api.ts) rather than using the Vercel AI SDK's useChat. This stream carries citations, per-claim verification verdicts, a confidence breakdown, and a cost report alongside the tokens. None of that maps onto the SDK's data protocol without encoding it as opaque blobs — at which point the SDK is only parsing data: lines, which is the twenty lines the parser already is. It also degrades correctly if the deployment buffers the response: a single flush containing every event parses exactly the same way, and only the progressive reveal is lost.

Ingestion is client-driven. The API has no background workers on serverless, so each POST /documents/{id}/ingest advances the pipeline as far as its time budget allows. runIngestion in lib/api.ts is the client half of that contract. Files upload sequentially rather than in parallel — concurrent ingestion triples the chance of hitting an embedding rate limit and stalls every progress bar at once.

Token appends use the functional setState form. Deltas arrive faster than React commits, so reading the previous answer out of a closure drops everything between renders.

Colours are validated, not chosen. The recall/latency chart uses categorical slots 1 and 2 from a design-system palette, with separate steps for light and dark surfaces; both pairs clear colourblind-separation, normal-vision, and contrast gates against their surface. The chart also ships a table view, so identity is never carried by colour alone.

Types are hand-written (lib/types.ts) rather than generated from the OpenAPI schema. The surface is small, and a codegen step that must run against a live backend is a worse trade than a file that breaks loudly when the API changes.


Limitations

  • Citation click-through uses the browser's PDF viewer via a #page=N fragment. It opens the right page; it does not highlight the exact span. Doing that properly needs pdf.js with a text layer and character offsets carried through chunking — worth doing, not done.
  • No conversation history. Each question is independent; there is no follow-up resolution ("what about the second one?"). The API supports a rewritten query but not a multi-turn context.
  • No auth. The demo is open. The API supports an optional X-API-Key, which the frontend does not send.
  • The config picker duplicates the config list from the API rather than fetching /evals/configs, so the picker renders instantly on a cold API. Adding a config means editing both places.

About

Next.js frontend for DocuMind - streamed answers with clickable citations, per-claim verification verdicts, and a live cost/latency/confidence badge, plus a benchmark page for the retrieval evaluation.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages