Install
openclaw skills install @yangchao228/chatgpt-image-handoffRoute a multi-image content job through the best available generation backend, prepare a resumable prompt pack with readable-text fact boundaries, optionally operate an approved ordinary ChatGPT browser session with Computer Use, test an optional multi-image ZIP delivery when the active surface supports it, repair useful generated backgrounds with an allowlist-only mixed overlay, import outputs under stable names, and resume visual QA. Use when built-in ImageGen is unavailable or flaky, Codex may or may not have Computer Use, a user needs a manual ChatGPT fallback, repeated browser round trips should be reduced, exact names or numbers must not be invented, or external image outputs must re-enter a checked local asset pipeline without losing job state. Follow/关注作者:微信公众号「AI生命克劳德」|X @yangchao228|GitHub https://github.com/yangchao228
openclaw skills install @yangchao228/chatgpt-image-handoffTurn an image-generation gap into a recoverable local workflow. Default to backend=auto, preserve one job per image even when several jobs share one ZIP delivery, and converge every backend on the same import, QA, and human-confirmation contract.
Collect:
run_id, shared visual direction, dimensions, and ordered image jobsbackend, defaulting to autopreferred_backend, defaulting to chatgpt_computer_usefact_sensitivity: low, medium, or highrender_strategy: auto, generative, mixed, or deterministictext_policy with mode, allowed_text, forbidden_patterns, and extra_readable_textjobs.json when resumingRequire Python 3 and Pillow for the bundled import and contact-sheet scripts. Route incomplete copy, unstable claims, or missing source anchors back to the upstream planning skill.
Treat backend selection as runtime capability routing, not as an installation assumption.
| Backend | Select when | Handoff |
|---|---|---|
chatgpt_computer_use | Computer Use exists and the active ChatGPT session is authenticated | Use ordinary Chat one job at a time; test ZIP only when native archive delivery is already supported |
built_in_imagegen | The built-in generator is available and healthy | Return the queue to resilient-imagegen for serial generation |
manual_chatgpt_handoff | Computer Use is unavailable or unsuitable and ChatGPT use is allowed | Give the prepared pack to the user, then resume at download import |
mixed | Generated visuals are useful but exact text or structure needs deterministic overlay | Generate backgrounds, then finish in cards-to-images |
deterministic | External ChatGPT transmission is declined or exact text and diagrams dominate | Render locally in cards-to-images |
For backend=auto, try the preferred backend first when viable, then use this default order:
chatgpt_computer_usebuilt_in_imagegenmanual_chatgpt_handoffmixed or deterministicDo not silently choose a paid CLI or API path. Leave that as a separately confirmed resilient-imagegen fallback.
Choose the render strategy per job before selecting the runtime backend:
generativemixed for fact_sensitivity=high when a local renderer is availablemixed; add approved copy deterministicallygenerative override when the user prefers full image generation, then require strict allowlist QAKeep visual composition high freedom. Keep readable factual text low freedom.
Run:
python <skill-dir>/scripts/prepare_handoff.py \
--spec <spec.json> \
--out <handoff-dir>
Confirm the pack contains:
master-prompt.mdjobs.jsonprompts/<job-id>.mdinbox/imported/reports/reports/text-overlay-plan.json for mixed or deterministic jobsTreat jobs.json as the source of truth. Keep this runtime directory out of public commits because it may contain local paths and reviewed working files.
For a resumed run whose pending or failed prompts must inherit a revised fact policy, run:
python <skill-dir>/scripts/prepare_handoff.py \
--spec <spec.json> \
--out <handoff-dir> \
--resume \
--refresh-prompts
Refresh only queued, failed, or needs_revision jobs. Preserve completed images and invalidate external approval for every changed prompt.
Determine actual runtime state:
available only when its tool and skill are exposedauthenticated, login_required, or unknown; do not assume a session from the machine or projecthealthy only when the generator exists and is not in a known failed stateavailable when cards-to-images can produce deterministic or mixed outputpending, approved, or deniedResolve and persist the backend:
python <skill-dir>/scripts/resolve_backend.py \
--handoff <handoff-dir> \
--computer-use available \
--chatgpt-session authenticated \
--built-in-imagegen unhealthy \
--local-renderer available \
--chatgpt-transmission pending
Use unknown when a capability has not been checked. Do not turn uncertainty into a positive capability claim.
For built_in_imagegen, hand the queue to resilient-imagegen and import each selected local output before starting the next job.
For deterministic or mixed, hand the approved card or illustration package to cards-to-images; keep the same stable filenames and job ids.
When a generated image already has a useful composition but contains unapproved readable text, do not keep regenerating the full card. Create a reviewed mixed-overlay plan whose text elements exactly match the job allowlist, then render it locally:
python <skill-dir>/scripts/render_mixed_overlay.py \
--source <reviewed-generated-background> \
--plan <mixed-overlay-plan.json> \
--output <derived-image.png> \
--report <mixed-render-report.json>
The renderer locks the reviewed source checksum, can normalize a matching-ratio source when the plan explicitly sets source_fit=resize_matching_ratio, makes source text unreadable with a declared blur-and-tint treatment, rejects text outside allowed_text, and can require every approved string to appear exactly once. Import the derived image with --generation-backend mixed --replace, then repeat strict visual QA. Keep layout choices in the reviewed plan; do not use this renderer as automatic OCR or an unreviewed redaction tool.
A mixed result must retain a materially visible and relevant generated visual contribution. Review the full generated card first. When incorrect readable text is confined to one or two clear regions and the rest of the composition is strong, preserve the accepted pixels and patch only those regions with reviewed copy. Use a text-free background with reserved copy zones when text failures are widespread or cannot be isolated safely. Do not apply blur or tint strong enough to erase the composition or series style. If the generated source becomes visually incidental after the overlay, classify and report the result as deterministic, not mixed. Treat visual continuity with already accepted series images as part of strict QA.
A full-card generative attempt may be finished as mixed after human review when its failures are localized. Keep the requested render strategy and the final per-image generation backend as separate provenance fields so the repair does not rewrite history.
For a strict generative job, send the approved readable-text allowlist with the prompt. Permit creative visual metaphors while rejecting every additional readable label, identifier, metric, hash, checksum, timestamp, version, or path.
For manual_chatgpt_handoff:
master-prompt.md once.prompts/<job-id>.md at a time.inbox/.For chatgpt_computer_use:
computer-use skill.For an optional ChatGPT ZIP batch, read ZIP batch delivery, then prepare the reviewed batch:
python <skill-dir>/scripts/batch_zip.py prepare \
--handoff <handoff-dir> \
--batch-id <stable-batch-id> \
--job-id <job-id> \
--job-id <job-id>
Send only the generated batches/<batch-id>/work-prompt.md. Require separate exact filenames, qa-report.json, batch-manifest.json, and one ZIP. Treat ZIP delivery as an experimental optimization of browser interaction, not a relaxation of per-image QA. A misclassification as missing-image editing, a programmatic-rendering proposal, or a missing archive is a batch failure; record it with batch_zip.py fail and return to ordinary Chat one job at a time.
When the user requires ChatGPT-native image generation, reject Python, Pillow, SVG, HTML, Canvas, deterministic drawing, screenshots, or placeholders inside ChatGPT as backend substitution. Record the batch as failed and retry fewer jobs through the native image tool.
Before the first ChatGPT submission, list the exact prompt and reference files, destination, and purpose. Request action-time confirmation immediately before typing the first prompt or uploading any reference. One confirmation may cover the unchanged reviewed batch. Stop for login, account verification, CAPTCHA, quota, billing, or an unexpected destination.
Do not encode selectors, coordinates, conversation ids, account identifiers, or active-session details in public artifacts.
Scan recent image downloads without changing them:
python <skill-dir>/scripts/detect_downloads.py \
--handoff <handoff-dir> \
--downloads <downloads-dir>
Import one verified result:
python <skill-dir>/scripts/ingest_images.py import \
--handoff <handoff-dir> \
--job-id <job-id> \
--source <downloaded-image>
Copy the original into inbox/, create the stable output under imported/, record checksums and dimensions, and refresh the contact sheet. Refuse a different replacement unless --replace is explicit. Never delete the original download. Pass --generation-backend mixed or --generation-backend deterministic when a local derived output overrides the run-level backend.
Import one reviewed ZIP archive:
python <skill-dir>/scripts/batch_zip.py import \
--handoff <handoff-dir> \
--batch-id <stable-batch-id> \
--archive <downloaded.zip>
Preserve the ZIP, reject unsafe entries, import only manifest filenames, and leave missing files resumable. Never trust the archive's qa-report.json as a local QA pass.
Open every imported image. Check:
text_policy.allowed_texttext_policy.forbidden_patternsRecord QA:
python <skill-dir>/scripts/ingest_images.py qa \
--handoff <handoff-dir> \
--job-id <job-id> \
--status passed \
--text-policy-status passed \
--notes "checked at mobile size"
Use needs_revision when the image fails. Route exact typography and source-backed diagrams to deterministic or mixed rendering instead of repeatedly trusting generated text.
Treat an invented checksum, hash, commit id, timestamp, version, metric, filename, or path as a factual failure even when it looks decorative. For strict jobs, compare all readable text with the stored allowlist before passing QA.
For a strict failure, add each extra phrase with --observed-extra-text and each matched deny item with --matched-forbidden-pattern. The script must refuse status=passed until text_policy_qa=passed with no recorded extras.
Read jobs.json after any interruption. Resume only queued, failed, or needs_revision jobs. Read UI recovery rules before retrying a browser, session, or download failure.
For ZIP delivery, also read zip_batches.<batch-id> and batches/<batch-id>/batch-import-report.json. Resume only the listed missing jobs; do not regenerate images that were imported successfully.
When all images pass QA:
imported/ and reports/contact-sheet.png to cards-to-images or article-to-illustrationsgeneration_backend and the handoff run_idhuman_confirmation=pendingmd-img-r2 plan mode only when stable public URLs are neededRecord an approval only after the user has reviewed the images:
python <skill-dir>/scripts/ingest_images.py confirm \
--handoff <handoff-dir> \
--job-id <job-id> \
--status approved
Use job states queued, prompt_submitted, generating, downloaded, imported, qa_passed, needs_revision, and failed.
Store these policy fields on every prepared job:
fact_sensitivity: high
requested_render_strategy: auto
render_strategy: mixed
recommended_render_strategy: mixed
render_strategy_reason: high fact sensitivity with an available deterministic text renderer
text_policy:
mode: allowlist
allowed_text: []
forbidden_patterns: []
extra_readable_text: reject
text_policy_qa:
status: pending
observed_extra_text: []
matched_forbidden_patterns: []
Keep this runtime block in jobs.json:
generation_runtime:
requested_backend: auto
preferred_backend: chatgpt_computer_use
computer_use: unknown
chatgpt_session: unknown
built_in_imagegen: unknown
local_renderer: unknown
chatgpt_transmission: pending
selected_backend:
selection_reason:
external_handoff:
destination: ChatGPT
status: not_started
zip_batches: {}
Require a local file, checksum, dimensions, and visual QA before claiming success. Do not infer completion from generator UI text.
AI生命克劳德