Skip to content
Automation
Skill

/image-generation

Generate an image from a prompt or edit an existing one (Gemini image model, standard library only, any Gemini key the resolver finds) and attach the file to the reply; generate a video with Veo when the google-genai SDK is installed. Use when the owner asks for a picture, logo,

From plugin
sutando
40179 skills18 hooks

Claude Code

$ npx -y skills add sonichi/sutando --skill image-generation --agent claude-code

SKILL.md

image-generation.SKILL.md
name: image-generation
description: "Generate an image from a prompt or edit an existing one (Gemini image model, standard library only, any Gemini key the resolver finds) and attach the file to the reply; generate a video with Veo when the google-genai SDK is installed. Use when the owner asks for a picture, logo, hero image, mockup, illustration, edited photo, or a short video clip."

Image and video generation

`scripts/generate.py` makes an image (or a video) from a prompt and prints **one JSON line** on stdout. Nothing to install for images: it calls the Gemini REST API with the standard library and takes the key from the credential resolver (`gemini-image`: the managed key of a desktop install, else `GEMINI_API_KEY` / `GEMINI_VOICE_API_KEY`). Never run `pip` for this skill; `Pillow` is optional (input resizing, jpg/webp conversion) and `google-genai` is only needed for `--video`.

Run it

G="<this skill's directory>/scripts/generate.py"
python3 "$G" --prompt "A flat-design mascot for a note-taking app, teal and cream"     # text-to-image
python3 "$G" --input photo.jpg --prompt "Replace the background with a sunset"          # edit
python3 "$G" --prompt "A cute robot" --output "<workspace>/results/media/robot.png"     # explicit path
python3 "$G" --video --prompt "A timelapse of a city at sunset" [--aspect 9:16]         # video (SDK)

Output lands at `<workspace>/results/media/generated-<ts>.png` (`.mp4` for video), which is inside the attachment allowlist, so the file can be sent as-is. `--model` overrides `IMAGE_MODEL` / `VIDEO_MODEL` (env, then this skill's `manifest.json` `config`).

Read the result

stdout is exactly one JSON line; progress goes to stderr.

| line | exit | what to do | |---|---|---| | `{"ok": true, "path": "...", "model": "...", "note"?: "..."}` | 0 | deliver the file (below) | | `{"ok": false, "error": "no_key", ...}` | 2 | say the no-key message, verbatim, and stop | | `{"ok": false, "error": "refused", "message": ...}` | 1 | say it was declined; offer a reworded prompt | | `{"ok": false, "error": "no_image", "message": ...}` | 1 | say what the model answered instead; offer a more concrete prompt | | `{"ok": false, "error": "api_error", "message": ...}` | 1 | say it failed on Google's side; one retry at most, then stop | | `{"ok": false, "error": "sdk_missing", ...}` (video) | 2 | say the SDK is missing; offer an image instead | | `{"ok": false, "error": "bad_input", ...}` | 2 | fix the input path; ask for the image again |

Every failure line carries a `remedy`; say it. Never imply an image exists when `ok` is false.

Deliver the image

The reply that carries the picture has the `[file: <path>]` marker **on its own line**, with the `path` from the JSON, and one short line of text:

Here's the mascot.
[file: /Users/…/workspace/results/media/generated-1789000000000.png]

In a task result this goes in the result file; in a direct reply, in the message. A generated image goes where it was asked (it is your own work, not private data): the room the request came from, or the DM when that is where it was asked.

Send it to a different AG2 Space room or DM

A picture for the room or DM the request came from goes with `[file:]` (above). Only a picture for another room ("send the boba tea picture to our AG2 Space DM") uses the upload script with `--post`, because the bridge uploads `[file:]` only to the task's own room. A voice task carries every room's id in its "known to the voice assistant" block: take the id from there, never `room_list`. The DM with a person is the two-member room named after the two of you ("Maddy-susan"); only when the block is missing, `room_list` then `room_inspect`. `posted: true` with an `event_id` means the chat message exists; a read of that event is the check. The script lives in the ag2space-voice skill, so this needs that skill installed.

U="<repo>/skills/ag2space-voice/scripts/upload-media.ts"
npx tsx "$U" --room '<room id>' --file "<path>" --name boba-tea.jpg --post

Put it into a project

When the picture belongs in a LaTeX/Typst project ("add figure 3, a pineapple"), upload it from disk with the upload script, without `--post` (it is filed on the Media page, not sent into the chat). **Never pass the image's base64 through a tool call yourself** (`room.media.upload` by hand): writing tens of thousands of characters takes minutes and corrupts the bytes.

U="<repo>/skills/ag2space-voice/scripts/upload-media.ts"
npx tsx "$U" --room '<room id>' --file "<path from generate.py>" --name pineapple.jpg --folder <project folder id>

It prints one JSON line: `{"ok": true, "name", "file_id", "mxc", "sha256", ...}`. The type comes from the bytes, so the extension in `name` may change (a JPEG is filed as `.jpg`). With `--folder`, the image is filed in that project folder, where Typst's `#image("<name>")` and LaTeX's `\includegraphics{<name>}` find it. Then change the file with `room.commons.changes.apply` to reference that `name`, and compile once (`room.commons.typst.compile` or `latex.compile`, passing the folder's media) to check the build. `{"ok": false, "error": "needs_approval"}` means the room requires an approval first: say so. `not_allowed` means the file is outside the attachment allowlist (generated images in `results/media` are inside it); any other error carries `detail`, say it. An error that still has `posted: true` means the picture is already in the chat: do not post it again.

What to say when it fails (verbatim)

  • `no_key`: "I can't generate images on this install yet: there is no Gemini key for image

generation. Add one in Agent settings → Agent → Gemini API, or ask again once your plan includes the managed key."

  • `refused`: "Gemini declined to generate that image: <message>. I can try a reworded prompt

(no real people's faces, no copyrighted characters)."

  • `no_image`: "Gemini answered with text instead of an image: <message>. Want me to try a mo
Read more
@sonichi
Ships withsutando

My AI Stand — Realtime by Day, Rewriting Itself by Night. Summon my AI superpower. Voice, vision, screen, meetings, calls when I'm engaged. Learns my patterns, ships its own code when I'm not. Runs across my Macs, interacts with people & their Stands.

Stars on GitHub

Momentum

stars in total
401
Star history of sonichi/sutando on GitHub, a chart by star-history.com

Other skills on sutando.

ag2space-voice

ag2space-voice

s.space voice surface — binds the room the s.space client announces to the voice session's origin, so work delegated by voice in…

@sonichi@sonichiInstall Skill
agent-activity

agent-activity

Streams what the agent is doing into the room, as rows the desktop client renders in an **events drawer** above the composer…

@sonichi@sonichiInstall Skill
agent-registry

agent-registry

Local Agent Registry — a standalone, dependency-free service that tracks running Claude Code (and other) agent instances. Agents…

@sonichi@sonichiInstall Skill
agent-room-ops

agent-room-ops

For an all-room analysis sweep, use the tested window collector and coverage contract in…

@sonichi@sonichiInstall Skill
answer-format

answer-format

Deterministic final-answer normalizer — a last-step pass for any task that ends in a *precise* answer (a number, a short string,…

@sonichi@sonichiInstall Skill
audio-transcribe

audio-transcribe

Transcribes audio files and voice notes to text via Gemini 2.5-flash. Integrates with Slack, Discord, and Telegram bridges so…

@sonichi@sonichiInstall Skill

More skills from other plugins.

agent-builder

agent-builder

Load immediately after an Agent intent, before the first agent_builder_* call. Governs how you create, configure, test, and…

n8n12d209k
@n8n-io@n8n-ioInstall Skill
browser-use

browser-use

Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…

@browser-use@browser-useInstall Skill
agent-browser

agent-browser

Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…

@vercel-labs-2@vercel-labs-2Install Skill
add-anydoc

add-anydoc

Add local office-document-to-Markdown conversion to NanoClaw agent containers with the pinned Firecrawl AnyDoc CLI. Use when…

@nanocoai@nanocoaiInstall Skill

Questions about image-generation.

Which coding agents can use image-generation?
image-generation installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.