Hosted at ocr.adityeah.ai.
Drop a file (image, PDF, Word, Excel, CSV, plain text), and chat with it.
Built on OpenAI gpt-4o-mini. No mode picker, no buttons to memorize —
just upload and ask.
- Extract anything. Images, scanned PDFs, text-PDFs, Word docs, Excel sheets, CSVs, and plain text are all auto-detected.
- Ask follow-ups in the same thread. "Summarize this." "What are the action items?" "Translate to Hindi." "Convert this table to JSON." The assistant has the document content for the rest of the conversation.
- Stay organized. Every file you drop starts a new thread, with a title derived from your first question. Threads persist across page refreshes (in your browser's localStorage).
cp .env.local.example .env.local
# paste your OPENAI_API_KEY (sk-...)
npm install
npm run dev
# → http://localhost:3002Rate limiting is a no-op locally if the Upstash env vars are blank. For
production-faithful testing, create a free Upstash project at
https://console.upstash.com and paste the REST URL + token into
.env.local.
src/app/page.tsx— orchestrates the chat: extract on client, append user message, POST/api/chat, append assistant message, auto-scrollsrc/app/api/chat/route.ts— the only API route; accepts{messages: ChatTurn[]}, runs OpenAI, returns Markdownsrc/lib/extract.ts— client-sideextractFromFile(file)→{text? | image?, attachmentName, attachmentType, ...}src/lib/thread-store.ts— localStorage CRUD +useThreadStore()hooksrc/lib/prompts.ts— single adaptiveSYSTEM_PROMPTsrc/lib/ratelimit.ts— Upstash sliding window (15/day per IP) with no-op dev fallbacksrc/lib/openai.ts— thin OpenAI client (used by /api/chat)src/lib/types.ts—Thread,Message,Attachment,ChatTurn, …src/components/ThreadList.tsx— sidebarsrc/components/MessageBubble.tsx— rendered messagesrc/components/Composer.tsx— input bar with file-attach + send
Next.js 16 (App Router) · TypeScript · Tailwind CSS v4 · OpenAI
gpt-4o-mini · pdfjs-dist · mammoth · xlsx · react-markdown ·
Upstash Redis (rate limiting) · nanoid
- 15 actions per IP per UTC day. Each call to
/api/chatcounts as 1 action (including follow-up questions in the same thread). MAX_DAILY_REQUESTSsite-wide safety cap (default 1000) — a hard ceiling so a viral burst can't run up the OpenAI bill.
8 MB per upload. The Composer rejects oversized files client-side and
/api/chat rejects oversized bodies server-side.
Threads live in your browser's localStorage only — they aren't sent anywhere except to OpenAI inside the chat request. Clearing your browser data clears your threads. (Cross-device sync via Upstash KV is a possible follow-up.)
Aditya · adityeah.ai · github.com/edityeah/ocr