Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/skills/infographic-agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ npx infographic-agent "Top 5 programming languages in 2026"

## 📋 Prerequisites

- **Python 3.8+**
- **Python 3.9+**
- **Gemini API Key**: Get a free key at [Google AI Studio](https://aistudio.google.com/apikey). Set it as:
```bash
export GEMINI_API_KEY="your-key"
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/infographic-agent/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: >
then gemini-3.1-flash-lite-image renders it into a PNG. No browser, Playwright, or Chromium dependencies —
the only requirement is Google's GenAI SDK. Fully portable to any agent CLI environment.
metadata:
version: "3.2.0"
version: "3.2.2"
author: "Infographic Agent contributors"
---

Expand Down
6 changes: 3 additions & 3 deletions .agents/skills/infographic-agent/bin/infographic-agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function findPython() {
if (match) {
const major = parseInt(match[1], 10);
const minor = parseInt(match[2], 10);
if (major >= 3 && minor >= 8) return candidate;
if (major >= 3 && minor >= 9) return candidate;
}
}
}
Expand Down Expand Up @@ -120,7 +120,7 @@ Examples:

if (!python) {
err(
"Python 3.8+ is required but was not found on your PATH.\n\n" +
"Python 3.9+ is required but was not found on your PATH.\n\n" +
" Install Python from https://www.python.org/downloads/ and make sure\n" +
" it is on your PATH, then re-run:\n\n" +
" npx infographic-agent ..."
Expand All @@ -132,7 +132,7 @@ if (!python) {

if (doInstall) {
print("Installing Python dependencies (google-genai, pillow)...");
const result = run(python, ["-m", "pip", "install", "--upgrade", "google-genai", "pillow"]);
const result = run(python, ["-m", "pip", "install", "--upgrade", "google-genai>=1.47.0", "pillow"]);
if (result.status !== 0) process.exit(result.status);

print(`
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/infographic-agent/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "infographic-agent",
"version": "3.2.0",
"version": "3.2.2",
"description": "Generate professional infographic PNGs from text with Gemini — a research agent (gemini-3.5-flash) prepares and validates the prompt, then gemini-3.1-flash-lite-image renders it. No browser/Playwright deps.",
"license": "MIT",
"author": "Ryan Baumann",
Expand Down
12 changes: 9 additions & 3 deletions .agents/skills/infographic-agent/portable_infographic.py
Original file line number Diff line number Diff line change
Expand Up @@ -637,9 +637,14 @@ def _normalize_to_png(data: bytes, mime: str):
return data, m


def _config_fields(config_type):
"""Return the declared fields across supported Pydantic SDK versions."""
return getattr(config_type, "model_fields", None) or getattr(config_type, "__fields__", {})


def _image_config(aspect: str, resolution: str):
"""Use newer quality controls only when the installed SDK supports them."""
fields = getattr(types.ImageConfig, "model_fields", {})
"""Request image size only when the installed SDK exposes that field."""
fields = _config_fields(types.ImageConfig)
kwargs = {"aspect_ratio": aspect}
if "image_size" in fields:
kwargs["image_size"] = resolution
Expand All @@ -649,7 +654,8 @@ def _image_config(aspect: str, resolution: str):


def _thinking_config():
fields = getattr(types.ThinkingConfig, "model_fields", {})
"""Use high thinking on current SDKs and dynamic thinking on older SDKs."""
fields = _config_fields(types.ThinkingConfig)
if "thinking_level" in fields:
return types.ThinkingConfig(thinking_level="HIGH", include_thoughts=True)
return types.ThinkingConfig(thinking_budget=-1, include_thoughts=True)
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/infographic-agent/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Runtime dependencies. Install with: pip install -r requirements.txt
# (or: pip install google-genai pillow)
google-genai>=1.0.0 # Gemini SDK — the two-agent research + image pipeline
google-genai>=1.47.0 # Gemini SDK — includes the typed image/thinking config surface tested here
pillow>=10.0.0 # transcodes the model's output to lossless PNG (crisp text)
62 changes: 62 additions & 0 deletions .agents/skills/infographic-agent/test_portable_infographic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import importlib.util
import unittest
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import patch


SCRIPT_PATH = Path(__file__).with_name("portable_infographic.py")
SPEC = importlib.util.spec_from_file_location("portable_infographic", SCRIPT_PATH)
portable = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(portable)


def config_type(*field_names):
class Config:
model_fields = {name: object() for name in field_names}

def __init__(self, **kwargs):
self.kwargs = kwargs

return Config


class SDKConfigCompatibilityTest(unittest.TestCase):
def test_current_sdk_requests_resolution_and_high_thinking(self):
fake_types = SimpleNamespace(
ImageConfig=config_type("aspect_ratio", "image_size"),
ThinkingConfig=config_type("thinking_level", "include_thoughts"),
)

with patch.object(portable, "types", fake_types):
image = portable._image_config("16:9", "1K")
thinking = portable._thinking_config()

self.assertEqual(image.kwargs, {"aspect_ratio": "16:9", "image_size": "1K"})
self.assertEqual(
thinking.kwargs,
{"thinking_level": "HIGH", "include_thoughts": True},
)

def test_sdk_1_47_falls_back_to_supported_fields(self):
fake_types = SimpleNamespace(
ImageConfig=config_type("aspect_ratio"),
ThinkingConfig=config_type("thinking_budget", "include_thoughts"),
)

with patch.object(portable, "types", fake_types), patch.object(portable, "warn") as warn:
image = portable._image_config("16:9", "1K")
thinking = portable._thinking_config()

self.assertEqual(image.kwargs, {"aspect_ratio": "16:9"})
self.assertEqual(
thinking.kwargs,
{"thinking_budget": -1, "include_thoughts": True},
)
warn.assert_called_once_with(
"Installed google-genai does not expose image_size; using the model's native resolution."
)


if __name__ == "__main__":
unittest.main()
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
- Replaced the oversized text-heavy hero with a 16:9 growth-loop diagram, added a separate 1200×627 social card, and embedded a purpose-built agent-evaluation loop in the article.
- Added reusable front-matter aliases for future detail-page renames and documented the workflow in the portfolio content skill.
- Hardened aliases against slashless duplicates, canonical-page collisions, private-route disclosure, stale canonicals, external targets, and bodyless entries.
- Installed Infographic Agent 3.2.0 and documented the required three-asset visual standard for every future hosted essay.
- Updated the vendored Infographic Agent skill to the merged 3.2.1 source, including Python 3.9 / `google-genai 1.47.0` compatibility and matching lock metadata, and documented the required three-asset visual standard for every future hosted essay.
- Archived the exact final image prompts and settings, including Gemini 3.1 Flash Image at 1K with high thinking, so all three visuals can be reproduced.
- Added a mandatory portfolio review workflow for every publishable content change: deterministic copy, claim, link, URL, image, metadata, and browser checks plus a bounded independent maker/checker loop.

Expand Down
2 changes: 1 addition & 1 deletion skills-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"source": "ryanbaumann/infographic-agent",
"sourceType": "github",
"skillPath": "skill/infographic-agent/SKILL.md",
"computedHash": "ec4962103a11264951bc9d431af6a9f6721e1df8f84e4df1c98bb6a2e0a2a416"
"computedHash": "9f2d5eb57d968332ef3d0fecb1b7c320967c4c820cb786ef86c3d8442681d3c6"
}
}
}
Loading