Skip to content

fix: Render standard-font PDFs in the proxy image, add a Gemini PDF example - #22

Merged
harshaneel merged 1 commit into
mainfrom
hg/example-gemini-pdf
Aug 6, 2026
Merged

fix: Render standard-font PDFs in the proxy image, add a Gemini PDF example#22
harshaneel merged 1 commit into
mainfrom
hg/example-gemini-pdf

Conversation

@harshaneel

Copy link
Copy Markdown
Owner

Summary

Fixes a real bug in the :proxy image, surfaced while writing a PDF example.

  • :proxy could not render standard-font PDFs. Alpine's poppler-utils ships without the Base-14 PDF fonts (Helvetica, Times, Courier), so pdftoppm rasterized those pages blank (exit 0, blank PNG), the proxy forwarded an empty image, and the model saw nothing. Every normal invoice, report, or document silently failed. Fix: add font-liberation (metric-compatible substitutes) to the proxy Dockerfile stage. Image grows ~41 MB to ~46 MB (measured 45.8 MB).
  • The bundled Debian images were never affected (they get DejaVu via fontconfig), so they are untouched.
  • The proxy-image PDF test previously passed on a blank page because it only checked that a valid PNG came back. It now decodes the render and requires dark pixels, so a fontless (blank) render fails.
  • New example examples/go/gemini-pdf: sends an embedded fake invoice through the Gemini SDK with a JSON schema and temperature 0, and extracts the fields. Runs with no setup; pass a path to use your own PDF.

Why the schema matters

Without a schema and temperature 0, the small local model returns a plausible-but-invented invoice. The example uses structured output so the model reads the page instead of hallucinating, matching the repo's existing structured-PDF test.

Test Plan

  • make lint clean, unit tests pass.
  • Strengthened docker_integration ProxyImage test passes on the fixed image. It fails on a fontless image (verified: render produces exactly zero dark pixels without the font package, ~9000 with it).
  • End to end against a real llama.cpp with the vision projector: with the fix, the example extracts the invoice's actual values (LK-2026-0042, Acme Robotics, $1,240.00, 2026-09-01); without it, the model returned hallucinated values because the page was blank.
  • Font package confirmed present on both linux/amd64 and linux/arm64 for the pinned Alpine base; font data is architecture-independent.

Note

The :proxy image published as v0.4.1 still has the blank-PDF bug; this warrants a v0.4.2 once merged.

🤖 Generated with Claude Code

…xample

Alpine's poppler-utils ships without the Base-14 PDF fonts (Helvetica,
Times, Courier), so the proxy image rasterized those pages blank and the
model received an empty image. Adds ttf-liberation, which supplies
metric-compatible substitutes. The image grows from about 41 MB to 46 MB.

The existing proxy-image PDF test only checked that a valid PNG came back,
so a blank page passed. It now requires the rendered page to contain dark
pixels, which is what fails when the fonts are missing.

Adds examples/go/gemini-pdf: it sends an embedded fake invoice through the
Gemini SDK and extracts the fields as structured JSON. Verified end to end
against a real llama.cpp with the vision projector; it returns the invoice's
actual values.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@harshaneel
harshaneel merged commit 95a5a31 into main Aug 6, 2026
3 checks passed
@harshaneel harshaneel mentioned this pull request Aug 6, 2026
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant