agentleFS
ciberjohnciberjohn/Hermes-Skills/openrouter-image-gen/SKILL.md

openrouter-image-gen

Skill17 starsChanged 2 months agoMITView on GitHub

Use when an illustration, cover, thumbnail, or any generated image is needed and local diffusion is unavailable. Generates via OpenRouter API, cheap models, no GPU, with recurring-character guidance for consistent article series art.

  • Reads credentials

The file

We split this skill into the rules it gives an agent

3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    If OPENROUTER_API_KEY is not set, the scripts fall back to reading it from OPENROUTER_ENV_FILE (default ~/.hermes/.env), looking for a line …

    line 28
  2. Very specific:

    Ask targeted questions: is the required text legible and correctly spelled?

    line 103
  3. Distinctive:

    Never print keys to chat or commit them.

    line 117

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

OpenRouter Image Generation

Generate images through OpenRouter's standard chat-completions endpoint using image-capable models. No local GPU, no ComfyUI workflow, no Docker: the image comes back inside the API response JSON.

Configuration Variables

Set these in your environment before running the pipeline, or document them in a .env file at your repo root:

VariableDescriptionExample
OPENROUTER_API_KEY(Required) OpenRouter API key for image generationsk-or-v1-xxxxxxxx
OPENROUTER_ENV_FILE(Optional) Path to a .env file containing the key, when it is not set directly in the environment~/.hermes/.env

If OPENROUTER_API_KEY is not set, the scripts fall back to reading it from OPENROUTER_ENV_FILE (default ~/.hermes/.env), looking for a line of the form OPENROUTER_API_KEY=....

When to Use

  • User asks for an illustration, cover, thumbnail, or any generated image and OpenRouter is the stated or available path.
  • Local diffusion (ComfyUI) is not available or the job is a one-off.
  • Text must render inside the image (T-shirts, signs, posters): Gemini image models handle text well — spell the text exactly in the prompt, then verify.

Endpoint & Response Shape (the critical bit)

  • POST https://openrouter.ai/api/v1/chat/completions with the normal chat payload: {"model": ..., "messages": [{"role":"user","content":"<prompt>"}], "n": 1}.
  • The image is returned embedded in the JSON as a data:image/...;base64,.... URL string. There is NO separate file download and NO image field you can trust to exist: message.content can be null while the image is buried somewhere else (e.g. nested content arrays, reasoning_details).
  • Always walk the whole response JSON recursively and collect every string starting with data:image (fallback: http(s) URLs matching image|png|jpe?g|webp). Decode the first hit. See scripts/generate_image.py.

Model Selection

Discover image-capable models live:

curl -s https://openrouter.ai/api/v1/models -o /tmp/or_models.json
# filter: architecture.output_modalities contains "image"

Cheap verified picks (re-check pricing via the API):

ModelPrompt $/tokenNotes
google/gemini-3.1-flash-lite-image~$0.25/MNano Banana 2 Lite — default "nice cheap" pick
google/gemini-2.5-flash-image~$0.30/MNano Banana; proven text quality
google/gemini-3.1-flash-image~$0.50/MNano Banana 2; best quality
openai/gpt-5-image~$10/Mpremium, rarely needed

Prompt guidance: state style ("editorial illustration", "slightly cartoonish"), composition ("wide 16:9"), and explicitly "no real logos, no brand names, no watermark".

The Recurring Series Character (recommended)

For article or blog illustrations, define ONE cartoon character and reuse it in every illustration so the series reads as a single body of work. Save the first good generation as the style anchor and include the full spec in every prompt.

Example spec (used by the author of this skill — customise freely):

  • A cartoon person of your choosing (example used by the author: stout/bald man, short goatee, round glasses, warm smile, plain black T-shirt, optionally a tech joke in green text)
  • Their workspace: cluttered desk with monitors (terminal text and/or data visuals), shelves with books and electronics, warm desk lamp, string lights, night window
  • A recurring motif: sci-fi paraphernalia (model starship, poster) — describe generically, never ask for trademarked logos
  • Palette: cool blues/teals/purples with warm amber accents; wide 16:9
  • Editorial cartoon style, clean linework, cel shading; "no real logos, no brand names, no watermark"

Verification (always — the model can lie about what it drew)

The configured aux vision model may not accept images (e.g. a text-only fallback → HTTP 400 "This model does not support image"). Workaround: send the PNG to a cheap vision-capable model over OpenRouter as a data: URL in a content array [{type:"text",text:...},{type:"image_url",image_url:{url:"data:image/png;base64,..."}}]. A verified vision model: google/gemini-3.5-flash-lite (check the current list — a gemini-3.1-flash without -image may not exist as a text model). Ask targeted questions: is the required text legible and correctly spelled? Are the requested elements present? See scripts/verify_image_vision.py.

Key Pitfall — stale API keys

  • An invalid/rotated OpenRouter key returns HTTP 401 {"error":{"message":"User not found."}}.
  • GET /models may STILL return 200 with an invalid key (the models list is not a strong auth check). Confirm the key with GET /api/v1/credits, which 401s on a bad key.
  • In Hermes, keys may live in multiple .env files and they can DIVERGE. The session environment may hold a stale key sourced earlier from the wrong file. Read the key from OPENROUTER_API_KEY explicitly (or the OPENROUTER_ENV_FILE path) rather than trusting os.environ alone.
  • Never print keys to chat or commit them.

Scripts

  • scripts/generate_image.py <out.png> "<prompt>" [model] — reads the key from OPENROUTER_API_KEY (or OPENROUTER_ENV_FILE), calls the API, walks the JSON for the image, writes the PNG. Default model google/gemini-3.1-flash-lite-image.
  • scripts/verify_image_vision.py <image.png> [model] — vision check of a PNG via OpenRouter (data URL), prints the model's description. Default model google/gemini-3.5-flash-lite.

Related

  • comfyui — local diffusion workflows (different path, no API cost).
  • baoyu-article-illustrator — style/palette guidance for article images (pair with this skill for consistent series art).
  • medium-story — article pipeline; drop the PNG in the story folder and reference it with a [*FILES*: name.png — description] placeholder.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.