Skip to content

fix(skill): save true PNG output (v3.0.1) - #5

Merged
ryanbaumann merged 1 commit into
mainfrom
claude/skill-image-format-fixes
Jul 7, 2026
Merged

fix(skill): save true PNG output (v3.0.1)#5
ryanbaumann merged 1 commit into
mainfrom
claude/skill-image-format-fixes

Conversation

@ryanbaumann

Copy link
Copy Markdown
Owner

Pull Request

Summary

Fixes a real bug found by running the skill pipeline end-to-end with a live Gemini key: the CLI was saving JPEG bytes under a .png filename, degrading text (the one thing an infographic must get right). gemini-3.1-flash-lite-image returns JPEG on the Gemini Developer API, and output_mime_type can't force PNG there:

output_mime_type is only supported in Gemini Enterprise Agent Platform mode, not in Gemini Developer API mode.

So the skill now transcodes the model output to lossless PNG. Bumps the skill to 3.0.1, which — with the publish workflow now on main — auto-publishes a fresh npm version on merge.

Changes

  • Lossless PNG output — transcode the model's image to PNG via Pillow so text stays crisp. Threads the actual mime type from the response through generation → refinement → save, and writes the extension matching the real bytes (save_image replaces a mismatched/absent image extension).
  • Refine loop correctnessrefine_image now re-sends the current image with its true mime type instead of a hardcoded image/png.
  • Graceful degradation — if Pillow is missing, the script saves the model's native format with an honest extension and a one-line warning; google-genai remains the only hard dependency.
  • Dependency + docs — add pillow to requirements.txt and --install; update README, SKILL.md, CHANGELOG; bump package.json to 3.0.1.

How Tested

  • Lint checks pass (npm run lint) — n/a: Python skill + docs only.
  • Unit tests pass (npm test) — n/a: no app source touched.
  • Production build succeeds (npm run build) — n/a: no app source touched.
  • Manual testing (live Gemini key):
    • py_compile + node --check pass; npm pack --dry-run clean (5 files, v3.0.1).
    • Full run: research (gemini-3.5-flash) + image (gemini-3.1-flash-lite-image) → file reports PNG image data, 768 x 1376 (previously JPEG).
    • Refinement round-trip returns PNG and re-saves as PNG; --output with no extension correctly yields .png.
    • Confirmed the API rejects output_mime_type on the Developer tier (hence the transcode approach).

Screenshots

Example output from this exact pipeline ("The rise of AI coding agents in 2026…", data-story, 9:16) — note the crisp, accurate text:

Image attached in the PR thread / shared separately.

🤖 Generated with Claude Code


Generated by Claude Code

Testing the pipeline end-to-end surfaced a real bug: gemini-3.1-flash-lite-image
returns JPEG on the Gemini Developer API, and output_mime_type cannot force PNG
there. The CLI was writing those JPEG bytes to a .png file — degrading text
quality and misnaming the file — and the refine loop hardcoded image/png when
re-sending the image.

Fixes:
- Transcode the model's output to lossless PNG via Pillow (crisp text, matching
  the skill's "text accuracy first" promise).
- Thread the real mime type from the response through generation, refinement,
  and saving; write the extension that matches the actual bytes.
- Degrade gracefully if Pillow is absent (save native format + warn) so
  google-genai stays the only hard dependency.
- Add pillow to requirements.txt and `--install`; bump skill to 3.0.1 and update
  README, SKILL.md, and CHANGELOG.

Verified end-to-end with a live key: research + image render now produces a
768x1376 PNG, and a refinement round-trips and re-saves as PNG.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018VA5q9TqsQjnmj6myJeB1g
@ryanbaumann
ryanbaumann merged commit e25ae92 into main Jul 7, 2026
2 checks passed
@ryanbaumann
ryanbaumann deleted the claude/skill-image-format-fixes branch July 7, 2026 21:42
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.

2 participants