First Commit: research-paper-presenter skill for hermes!
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
generate_images.py — Generate slide visuals with OpenAI's gpt-image-2.
|
||||
|
||||
Reads a prompts file (JSON list) and writes one PNG per entry into --assets.
|
||||
gpt-image-2 has reasoning + strong in-image text rendering, so it is well suited
|
||||
to diagrams, labelled schematics and infographics — not just decorative art.
|
||||
|
||||
Prompts file format (JSON):
|
||||
[
|
||||
{"id": "attention_schematic",
|
||||
"prompt": "Clean technical diagram of scaled dot-product attention ...",
|
||||
"shape": "landscape"},
|
||||
{"id": "rnn_vs_transformer", "prompt": "...", "shape": "portrait"}
|
||||
]
|
||||
|
||||
Usage:
|
||||
export OPENAI_API_KEY=...
|
||||
python3 generate_images.py prompts.json --assets workdir/assets
|
||||
# options: --model gpt-image-2 --quality high --style-suffix "..."
|
||||
|
||||
Each PNG is saved as <id>.png — reference that exact filename in the deck spec's
|
||||
"image" field.
|
||||
|
||||
NOTE for Codex/Hermes: if your agent runtime already has native gpt-image-2 image
|
||||
generation, you may instead generate images directly and just save them as
|
||||
<id>.png into the assets dir — this script is the portable API fallback.
|
||||
"""
|
||||
import argparse
|
||||
import base64
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
SIZES = { # gpt-image-2 supported sizes
|
||||
"landscape": "1536x1024",
|
||||
"portrait": "1024x1536",
|
||||
"square": "1024x1024",
|
||||
}
|
||||
|
||||
# Appended to every prompt so generated visuals share a coherent look that sits
|
||||
# well on the deck background. Override with --style-suffix.
|
||||
DEFAULT_STYLE = (
|
||||
" Modern flat editorial illustration / technical diagram style. "
|
||||
"Crisp vector-like shapes, generous whitespace, high contrast, "
|
||||
"legible labels, restrained palette of deep navy, cyan and violet on a "
|
||||
"near-black background. No watermark, no signature, no stock-photo look."
|
||||
)
|
||||
|
||||
|
||||
def make_client():
|
||||
try:
|
||||
from openai import OpenAI
|
||||
except ImportError:
|
||||
sys.exit("openai SDK not installed — run: pip install openai")
|
||||
key = os.environ.get("OPENAI_API_KEY")
|
||||
if not key:
|
||||
sys.exit("OPENAI_API_KEY is not set.")
|
||||
return OpenAI()
|
||||
|
||||
|
||||
def generate(client, model, prompt, size, quality, transparent):
|
||||
kwargs = dict(model=model, prompt=prompt, size=size, n=1)
|
||||
# gpt-image models support quality + optional transparent background
|
||||
if quality:
|
||||
kwargs["quality"] = quality
|
||||
if transparent:
|
||||
kwargs["background"] = "transparent"
|
||||
resp = client.images.generate(**kwargs)
|
||||
return base64.b64decode(resp.data[0].b64_json)
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("prompts")
|
||||
ap.add_argument("--assets", default="assets")
|
||||
ap.add_argument("--model", default="gpt-image-2")
|
||||
ap.add_argument("--quality", default="high",
|
||||
help="low | medium | high (gpt-image-2)")
|
||||
ap.add_argument("--style-suffix", default=DEFAULT_STYLE)
|
||||
ap.add_argument("--overwrite", action="store_true")
|
||||
args = ap.parse_args()
|
||||
|
||||
os.makedirs(args.assets, exist_ok=True)
|
||||
with open(args.prompts) as fh:
|
||||
prompts = json.load(fh)
|
||||
|
||||
client = make_client()
|
||||
ok = 0
|
||||
for item in prompts:
|
||||
iid = item["id"]
|
||||
out = os.path.join(args.assets, f"{iid}.png")
|
||||
if os.path.exists(out) and not args.overwrite:
|
||||
print(f"· skip {iid} (exists)")
|
||||
ok += 1
|
||||
continue
|
||||
size = SIZES.get(item.get("shape", "landscape"), SIZES["landscape"])
|
||||
prompt = item["prompt"].strip() + args.style_suffix
|
||||
for attempt in range(1, 4):
|
||||
try:
|
||||
data = generate(client, args.model, prompt, size,
|
||||
args.quality, item.get("transparent", False))
|
||||
with open(out, "wb") as fh:
|
||||
fh.write(data)
|
||||
print(f"✓ {iid} ({size})")
|
||||
ok += 1
|
||||
break
|
||||
except Exception as e:
|
||||
wait = 3 * attempt
|
||||
print(f" ! {iid} attempt {attempt} failed: {e} "
|
||||
f"(retry in {wait}s)" if attempt < 3
|
||||
else f" ✗ {iid} gave up: {e}")
|
||||
if attempt < 3:
|
||||
time.sleep(wait)
|
||||
print(f"\n{ok}/{len(prompts)} images ready in {args.assets}/")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user