Install
openclaw skills install @lxyd-ai/gpt-image2Generate high-quality images with GPT Image 2 (OpenAI gpt-image-2) via the ClawdChat tool gateway. Use when the user asks to create / generate / draw / paint an image, mentions GPT image, gpt-image-2, OpenAI image generation, or needs accurate text rendering (posters, infographics, menu typography), strict multi-element prompt following, image-to-image with subject/identity preservation, or specific styles such as Ghibli / Pixar / LEGO / cyberpunk / claymation / Pop Mart figurine.
openclaw skills install @lxyd-ai/gpt-image2Powered by ClawdChat — calls OpenAI
gpt-image-2through the Uno tool gateway.
Two thin command-line invocations against the public ClawdChat tool gateway:
| Tool slug | Purpose | Cost |
|---|---|---|
gpt-image-2.gpt_image2_submit | Submit a generation job, returns job_id immediately (async) | 300 credits / call |
gpt-image-2.gpt_image2_result | Poll job status / fetch image URL when ready | 0 credits |
This skill ships no local Python code. It defers all credential, transport and rate-limit handling to the uno-cli companion skill.
~/.clawdchat/credentials.json. The file is created and owned by the uno-cli skill; this skill never opens, prints or copies it.uno login in uno-cli, which opens an OAuth flow on https://clawdchat.cn and stores the resulting token.gpt_image2_submit deducts 300 credits from that account.prompt text and any reference_image_urls are sent to the ClawdChat gateway over HTTPS. Do not paste private, confidential, or personally-identifying content into the prompt unless you are comfortable with the gateway's data handling — see https://clawdchat.cn for the data policy.uno logout (managed by uno-cli).Every gpt_image2_submit call costs the logged-in account real credits. The agent must:
n > 1) or retries, treat each submission as a separate spending event and confirm again unless the user has pre-authorised the batch.error responses, surface the error to the user instead of silently retrying.Polling via gpt_image2_result is free; only submit spends credits.
This skill depends on the uno-cli skill (declared in metadata.openclaw.skills).
Install uno-cli (skipping if already installed):
clawhub install uno-cli
On platforms that honour metadata.openclaw.skills, this dependency is installed automatically when this skill is installed.
Log in once:
uno login
The login flow, credential storage, and refresh are entirely handled by uno-cli. This skill only invokes uno call ... afterwards.
If
unois not onPATH, replace it in the examples below withpython /path/to/uno-cli/bin/uno.py.
A single 1024×1024 image typically takes ~150 s, longer than the default MCP 60 s timeout. Always use the submit → poll-result pattern.
uno call gpt-image-2.gpt_image2_submit --compact \
--args '{"prompt":"A shiba inu under cherry blossoms, sunny afternoon","size":"1024x1024","style":"ghibli_anime"}'
Response (already flattened by uno-cli — no need to unwrap content[0].text):
{"success": true, "data": {"status": "pending", "job_id": "0b84b8f0f0c8", "estimated_seconds": 150}, "meta": {"latency_ms": 120, "credits_used": 300}}
Record data.job_id.
uno call gpt-image-2.gpt_image2_result --compact --timeout 70 \
--args '{"job_id":"0b84b8f0f0c8","wait_seconds":50}'
wait_seconds=50 makes the server-side wait 50 s (within the 60 s MCP envelope); --timeout 70 adds a small client buffer.
Repeat the call until data.status is one of:
done — image ready, URLs in data.items[].url.error — generation failed, message in data.error.pending / running — call again immediately. Do not add a client-side sleep; the server already waited 50 s on your behalf.Three to five iterations (~150–250 s total) is normal.
RESP=$(uno call gpt-image-2.gpt_image2_submit --compact \
--args '{"prompt":"Van Gogh starry night","style":"oil_painting_vangogh"}')
JOB_ID=$(echo "$RESP" | python3 -c "import json,sys; print(json.load(sys.stdin)['data']['job_id'])")
for i in 1 2 3 4 5 6; do
R=$(uno call gpt-image-2.gpt_image2_result --compact --timeout 70 \
--args "{\"job_id\":\"$JOB_ID\",\"wait_seconds\":50}")
STATUS=$(echo "$R" | python3 -c "import json,sys; print(json.load(sys.stdin)['data']['status'])")
[ "$STATUS" = "done" ] && echo "$R" && break
[ "$STATUS" = "error" ] && echo "$R" && exit 1
done
| Field | Meaning | Values |
|---|---|---|
prompt | Image description (required, any language) | free text |
size | Image dimensions | 1024x1024 (default), 1024x1536 (portrait), 1536x1024 (landscape), auto |
n | Number of images to generate | 1–4 (default 1) |
style | Built-in style preset | one of the 20 keys below |
reference_image_urls | Reference images (image-to-image) | URL string, comma-separated for multiple |
| key | description |
|---|---|
ghibli_anime | Studio Ghibli / hand-drawn anime |
pixar_3d | Pixar / Disney 3D animation |
claymation | Stop-motion claymation (Laika / Aardman) |
lego_brick | LEGO bricks |
popmart_figurine | Blind-box / Pop Mart figurine |
isometric_game | Isometric 2.5D game scene |
cinematic_photo | Cinematic photorealism (35mm) |
polaroid_film | Polaroid film snapshot |
watercolor_ink | Watercolour / East-Asian ink wash |
oil_painting_vangogh | Van Gogh impasto oil painting |
cyberpunk_neon | Cyberpunk neon nightscape |
vintage_infographic | Retro infographic / data poster |
movie_poster | Movie poster (large title + still) |
flat_vector | Flat-vector illustration / banner |
pixel_8bit | Pixel art (8/16-bit) |
papercraft_layered | Layered papercraft |
exploded_diagram | Exploded technical diagram |
dreamcore_liminal | Dreamcore / liminal space |
knolling_flatlay | Top-down knolling / flat-lay |
botanical_engraving | Botanical engraving / antique illustration |
gpt_image2_result tool already sleeps 50 s server-side — never add an extra client-side sleep between polls.--timeout 70 for result calls (50 s server wait + buffer).reference_image_urls with a style preset for "restyle while keeping the subject".submit returns success=false, surface the error/hint fields to the user.running, tell the user the job can be re-polled later with the same job_id.Already flattened by uno-cli:
{
"success": true,
"data": {"status": "...", "job_id": "...", "items": [{"url": "..."}]},
"meta": {"latency_ms": 120, "credits_used": 300}
}
Read data.status, data.job_id, data.items[].url directly.
Errors:
{"success": false, "error": "...", "hint": "..."}