Image And Video Generation Skill
Use this skill when OpenClaw should call this platform relay API for:
- VEO video models
- Banana image models
- Sora video models
Read these references before using the scripts:
Environment
Preferred:
EASYCLAW_PLATFORM_API_TOKEN
Compatible fallback:
CHANJING_PLATFORM_API_TOKENEASYCLAW_PLATFORM_API_KEYEASYCLAW_PLATFORM_API_SECRETCHANJING_PLATFORM_API_KEYCHANJING_PLATFORM_API_SECRET
Optional base URL override:
EASYCLAW_PLATFORM_BASE_URLCHANJING_PLATFORM_BASE_URL
Important guidance:
- Always tell the user to get the platform token from
http://easyclaw.bar/shuziren/user/ - The token is issued by this platform, not by the upstream provider
- The base URL defaults to
http://easyclaw.bar/shuzirenapi - Do not modify OpenClaw core code or
openclaw.jsonto make this skill work
Important Rules
- Only execute the provided Python scripts under
scripts/ - Do not hand-write HTTP requests
- Do not probe unrelated platform routes such as
/api/me, auth routes, or non-skill routes - If a needed capability is not exposed by an existing script, update a script first
- Submit requests only through
scripts/generate_video.py - Query an existing task only through
scripts/fetch_video.py scripts/generate_video.pymust submit exactly one task for one user intent- After submission, the skill must create the watcher in the same run unless the user explicitly asks for
--no-watch - The watcher must be implemented inside the skill scripts, not by modifying OpenClaw core behavior
- The watcher checks task status every 30 seconds by default
- Before creating the watcher, pass the current OpenClaw session binding to
scripts/generate_video.pywith--notify-session-key --notify-session-keymay be either the real OpenClaw session key or the current delivery target such aseasyclaw:bot:11- Prefer the current session key from
session_status; do not guess another session when the current one can be resolved - When the task reaches a terminal state, the watcher must return the result and delete its own cron job
- If watcher creation fails, tell the user submission succeeded but automatic notification was not armed
- Do not promise automatic notification unless a non-empty watcher
job_idis returned - Do not claim there will be fallback polling or periodic checking unless that behavior is actually implemented and armed
- Pass only the parameters the user specified
- Prefer guided builder flags because they validate model-specific requirements and return clearer errors
- Use raw JSON or raw multipart mode only when the user needs fields not exposed by the guided builder
Async Workflow
For VEO, Banana, and Sora generation:
- Run
scripts/generate_video.py - Let the script submit the request
- Pass the current session binding with
--notify-session-keyso the watcher can write the final result back to the originating session - Let the script create the cron watcher in the same execution by default
- Return the submission result and watcher state
- The watcher will call
scripts/cron_watch_task.pyevery 30 seconds - If the task is still running, the watcher returns exactly
NO_REPLY - If the task succeeds or fails, the watcher writes the final result into the original session, returns
NO_REPLY, and removes the cron job
Do not replace this with model-side polling or ad hoc direct requests.
Script Selection
- Submit generation request:
scripts/generate_video.py - Query one task by id:
scripts/fetch_video.py
Submit Modes
scripts/generate_video.py supports:
-
Guided builder mode
- Use flags such as
--prompt,--reference-file,--image-url,--style,--size,--aspect-ratio - This mode validates model-specific rules
- Use
--list-modelsor--describe-model <model>when guidance is needed
- Use flags such as
-
JSON request mode
- Use
--payload-jsonor--payload-file - Use this when the upstream payload needs custom JSON fields
- Use
-
Multipart form-data mode
- Use repeated
--field name=value - Use repeated
--file-field name=path - Use this for local file uploads such as
input_reference
- Use repeated
Do not mix JSON payload args with multipart field args in one command.
Model Usage
VEO video models
Typical models:
veo_3_1-fastveo_3_1-fast-flveo_3_fastveo_3
Rules:
veo_3_1-fastsupports text-to-video and reference-image video with up to 3 imagesveo_3_1-fast-flrequires 1 or 2 images- If the user selects
veo_3_1-fast-fland does not provide the required images, stop and tell them exactly what is missing - VEO JSON mode does not accept HTTP image URLs for
input_reference; use local files or Base64 JSON in raw mode
Banana image models
Standard Banana:
nano_banana_2nano_banana_pronano_banana_pro-1Knano_banana_pro-2Knano_banana_pro-4K
Gemini Banana:
nano_banana_2-landscapenano_banana_2-portraitnano_banana_pro-1K-landscapenano_banana_pro-1K-portraitnano_banana_pro-2K-landscapenano_banana_pro-2K-portraitnano_banana_pro-4K-landscapenano_banana_pro-4K-portrait
Rules:
- Standard Banana uses
promptplus optionalmetadata - Gemini Banana uses
contentsplusgenerationConfig - Guided builder mode supports both families and performs basic validation
Sora video models
Typical models:
sora-2-landscape-10ssora-2-portrait-10ssora-2-landscape-15ssora-2-portrait-15ssora-2-pro-landscape-25ssora-2-pro-portrait-25ssora-2-pro-landscape-hd-15ssora-2-pro-portrait-hd-15s
Rules:
- Prompt is required
image_urland localinput_referenceare mutually exclusive- Use raw JSON or raw multipart when extra provider-specific fields are required
Examples
Print the built-in model guide:
python "{baseDir}/scripts/generate_video.py" --list-models
Describe one model:
python "{baseDir}/scripts/generate_video.py" --describe-model "veo_3_1-fast-fl"
Submit VEO with JSON:
python "{baseDir}/scripts/generate_video.py" --model "veo_3_1-fast" --payload-json "{\"model\":\"veo_3_1-fast\",\"prompt\":\"a cat running in snow\",\"size\":\"1920x1080\"}"
Submit VEO with local reference files:
python "{baseDir}/scripts/generate_video.py" --model "veo_3_1-fast" --prompt "animate this portrait" --reference-file "C:\path\reference1.jpg" --reference-file "C:\path\reference2.jpg"
Submit VEO start/end frame mode:
python "{baseDir}/scripts/generate_video.py" --model "veo_3_1-fast-fl" --prompt "animate between these two frames" --start-frame-file "C:\path\start.jpg" --end-frame-file "C:\path\end.jpg"
Submit Banana standard:
python "{baseDir}/scripts/generate_video.py" --model "nano_banana_pro" --prompt "a coffee cup on a wooden desk" --aspect-ratio "1:1" --reference-url "https://example.com/ref.png"
Submit Gemini Banana:
python "{baseDir}/scripts/generate_video.py" --model "nano_banana_2-landscape" --prompt "a futuristic city skyline"
Submit Sora with image URL:
python "{baseDir}/scripts/generate_video.py" --model "sora-2-landscape-10s" --payload-json "{\"model\":\"sora-2-landscape-10s\",\"prompt\":\"turn this into a cinematic teaser\",\"image_url\":\"https://example.com/source.png\",\"style\":\"cinematic\"}"
Submit only without watcher:
python "{baseDir}/scripts/generate_video.py" --model "veo_3_1-fast" --payload-file "C:\path\payload.json" --no-watch
Query an existing task:
python "{baseDir}/scripts/fetch_video.py" --task-id "task_123"
Scan to join WeChat group