ecarjat teaches Mike to read scanned PDFs

Tabular reviews stop returning blank cells when the document is a scan instead of a real text file.

discoverycontract-review

Plenty of legal documents arrive as scans - a photocopy saved as a PDF with no underlying text layer. Until now, when @ecarjat's fork tried to pull structured data out of those files for a tabular review, it just came back empty and the user was none the wiser.

The fix routes scanned PDFs straight to the AI as images instead of text. Google's Gemini and Anthropic's Claude both accept PDFs natively and now handle these documents directly; OpenAI doesn't support that yet, so those cells come back with a clear note rather than a silent blank. Worth flagging: sending whole scanned PDFs to an AI is meaningfully more expensive than sending extracted text, so anyone borrowing this will want a page cap alongside it.

So what Anyone running document review over a mix of native and scanned PDFs - i.e. almost any litigation or M&A workflow - should care, because this is the difference between a usable table and a half-empty one.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

1 commit from ecarjat/mike, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
74564426 feat: native PDF vision for scanned documents Emmanuel Carjat 2026-05-11 ↗ GitHub
commit body
Add multimodal PDF processing so scanned PDFs (no text layer) can be
analysed by Gemini and Claude models instead of returning empty results.

- streamGeminiMultimodal: pass raw PDF bytes as inlineData to Gemini
- streamClaudeMultimodal: pass raw PDF bytes as document content block to Claude
- loadSourceTexts: store rawPdfBase64 when pdfjs extracts no text
- queryGeminiAllColumns: dispatch to vision path for Gemini/Claude;
  return a clear grey error cell for OpenAI (no native PDF support)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-398.md from inside the repo you want the changes in.

⬇ Download capture-thread-398.md