Skip to content

Repository files navigation

Dossier

Answers you can check. Dossier takes a pile of text nobody has time to read and turns it into an answer with its sources attached. It comes in two halves that do the same job and differ only in who goes and fetches the text.

Documents. Bring a PDF, a block of pasted text, or a URL. Ask questions about it. Answers cite the passages they came from, expandable inline, and the model is told to say the answer is not there rather than invent one.

Companies. Name a company and say what you want from them. A tool-using agent searches the web, reads their site, looks for recent signals and decision makers, and returns a brief with talking points and an opening line. Every search and every page it opens is printed as it happens.

What it does

Documents:

  1. Ingest. Extract text from a PDF, a pasted block, or a fetched web page.
  2. Chunk. Split on paragraph boundaries with overlap, dropping fragments.
  3. Embed. Voyage voyage-3, batched, with the document input type.
  4. Store. Postgres with pgvector, through Supabase.
  5. Ask. Embed the question with the query input type, pull the nearest chunks, and stream an answer grounded in them.

Companies:

  1. Check the cache. A brief for the same company inside seven days returns instantly and costs nothing.
  2. Research. The agent loops over web_search and fetch_website until it has enough, capped at six iterations.
  3. Submit. A terminal tool call returns the brief as structured data, normalised so a missing array never breaks the render.
  4. Account. Token usage is logged per request and the estimated cost is shown.

Every endpoint streams NDJSON, so the interface shows real progress rather than a spinner: ingest prints each stage, chat renders citations before the first token of the answer, and research prints each tool call as the agent makes it.

Stack

Piece Choice
Framework Next.js 16, App Router, node runtime
Embeddings Voyage voyage-3
Vector store Supabase Postgres with pgvector
Answering Anthropic claude-haiku-4-5
Research agent Anthropic claude-sonnet-4-6 with tool use
Web search Tavily
Page reading Native fetch, shared by both halves
PDF extraction unpdf
Styling Tailwind 4

Setup

npm install
npm run dev
Variable For
VOYAGE_API_KEY Document embeddings
ANTHROPIC_API_KEY Answering and the research agent
SUPABASE_URL Vector store, brief cache, usage log
SUPABASE_ANON_KEY Vector store, brief cache, usage log
TAVILY_API_KEY Agent web search

The database needs four tables and two RPCs before anything works. The full schema is in TECHNICAL.md.

Layout

app/page.tsx                 landing, both entry points
app/documents/page.tsx       upload and chat
app/companies/page.tsx       research form, live agent trace, brief
app/api/ingest/route.ts      extract, chunk, embed, store; streams progress
app/api/chat/route.ts        retrieve, then stream a grounded answer
app/api/research/route.ts    rate limit, cache, run the agent, log usage
lib/chunker.ts               paragraph-first splitting with overlap
lib/embed.ts                 Voyage client, document and query modes
lib/store.ts                 Supabase reads and writes for documents
lib/scrape.ts                page fetch and text reduction, shared
lib/agent.ts                 the research loop and its tools
lib/cache.ts                 seven day brief cache
lib/rate-limit.ts            per IP monthly cap and cost estimation
lib/types.ts                 shared shapes, including both stream event unions

How it works

TECHNICAL.md covers the chunking strategy and why it cascades through three boundary types, why the document and query embedding calls are separate functions, the database schema and both RPCs, the NDJSON streaming protocol shared by all three endpoints, the agent loop and its terminal tool, and the known limits.

About

Chat with your own documents. Upload a PDF, text, or URL and get answers with citations. RAG over pgvector.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages