Plume AI Image Service
name: plume-image
by dake6767 · published 2026-03-22
$ claw add gh:dake6767/dake6767-plume-image---
name: plume-image
description: |
Plume AI image generation and editing service. Auto-triggers when users send images or describe image needs.
Supports: text-to-image, image-to-image, background removal, watermark removal, style transfer, text-to-video, image-to-video.
Activate when user mentions: generate image, edit image, remove background, change background, remove watermark,
text-to-image, image-to-image, AI art, style transfer, generate poster, photo editing, generate video, AI video,
animate this image, make it move, image-to-video, make image into video, seedance2, seedance.
allowed-tools: Bash(python3 ${CLAUDE_SKILL_DIR}/scripts/*), Bash(cat ~/.openclaw/media/plume/*)
metadata: {"openclaw": {"requires": {"env": ["PLUME_API_KEY"]}, "primaryEnv": "PLUME_API_KEY"}}
---
# Plume AI Image Service
Help users complete AI image generation and editing through natural language.
🚨 Critical Workflow Rules (Must Follow)
**All tasks must use: `create` → `poll_cron.py register` → reply to user immediately → end**
**Strictly prohibited:**
**Correct approach:**
⚠️ Mandatory Pre-check (Run Before Every Use)
python3 ${CLAUDE_SKILL_DIR}/scripts/check_config.py> To use the Plume AI image service, you need to configure your API Key first:
> 1. Visit [Plume Platform](https://design.useplume.app/openclaw-skill) to register and obtain an API Key
> 2. Edit `~/.openclaw/openclaw.json`, add to `skills.entries`:
> ```json
> "plume-image": { "env": { "PLUME_API_KEY": "your-key" } }
> ```
> Or add `PLUME_API_KEY=your-key` to the `~/.openclaw/.env` file
> 3. Enter `/restart` to apply changes
Background Polling Behavior
This skill starts a background Python process via `poll_cron.py register` to poll task status. Results are delivered via `openclaw message send` when the task completes.
Supported categories (fixed enum, do not invent)
| category | Alias | Use case | Default |
|----------|-------|----------|---------|
| `Banana2` | 香蕉 | text-to-image / image-to-image / style transfer | ✅ default for images |
| `BananaPro` | 香蕉Pro | text-to-image / image-to-image (user explicitly requested) | |
| `remove-bg` | | background removal | |
| `remove-watermark` | | watermark removal | |
| `seedream` | 即梦/豆包即梦 | Doubao Seedream image generation | |
| `veo` | | text-to-video / image-to-video | ✅ default for videos |
| `seedance2` | | Seedance2 video (user explicitly requested) | |
**Style transfer (cartoon, Pixar, watercolor, etc.) defaults to `Banana2` + `--prompt` describing the style, unless user explicitly requests BananaPro. Do not invent new categories.**
Image/Video Specs
Multi-turn Dialog / Image-to-Image
When the user requests modifications to an existing image (style transfer, background removal, image-to-video, etc.), first determine the image source:
Determine image source (priority: highest to lowest)
1. **User sent both image and text instructions in the current turn** → `transfer --file <attachment path>` to upload to R2, get `image_url`, process per text instructions
2. **User sent only an image in the current turn, no text** → **do not create a task**, reply "Got your image. What would you like to do with it?" and wait for next message
3. **User sent an image in the previous turn, text instructions in the current turn** → `transfer` upload the previous turn's image, process per current text instructions
4. **User references "last/this/just generated" image** → read `last_result_{channel}.json` to get `result_url`
5. **None of the above** → prompt user to send an image
Read last result
Files are isolated by channel to prevent cross-channel mix-up:
# {channel} = current channel: feishu / qqbot / telegram
cat ~/.openclaw/media/plume/last_result_{channel}.jsonReturns JSON:
{"task_id": "xxx", "result_url": "https://pics.useplume.app/...", "local_file": "...", "media_type": "image", "created_at": ...}**Must use `result_url` (remote URL) as `--image-url`; do NOT use `local_file`.**
Image-to-image example
# 1. Read last result (using QQ Bot channel as example)
cat ~/.openclaw/media/plume/last_result_qqbot.json
# get result_url = https://pics.useplume.app/xxx.png
# 2. Create image-to-image task (processing_mode auto-detected as image_to_image)
python3 ${CLAUDE_SKILL_DIR}/scripts/process_image.py create \
--category Banana2 \
--image-url "https://pics.useplume.app/xxx.png" \
--prompt "transform into Pixar 3D animation style"
# 3. Register polling (same as standard flow)
python3 ${CLAUDE_SKILL_DIR}/scripts/poll_cron.py register \
--task-id <id> --channel qqbot --target "qqbot:c2c:XXXX" --interval 5 --max-duration 1800Context keywords
When the user says any of the following, read last_result_{channel}.json for image-to-image:
Unified Workflow
All tasks: `create` → `poll_cron.py register` → reply to user immediately → end
Create task
python3 ${CLAUDE_SKILL_DIR}/scripts/process_image.py create \
--category <category> \
--prompt "<English prompt>" \
[--processing-mode text_to_image|image_to_image|text_to_video] \
[--image-url <r2_url>] \
[--first-frame-url <url>] \
[--image-size 2K] \
[--aspect-ratio 9:16]**Output format:** JSON, always check the `success` field
| code | User message |
|------|-------------|
| `INSUFFICIENT_CREDITS` | Inform user that Plume account credits are insufficient, guide them to [Plume Platform](https://design.useplume.app) to top up and retry |
| `CREDITS_ACCOUNT_NOT_FOUND` | Inform user that credits account has not been created, guide them to [Plume Platform](https://design.useplume.app) to register |
| `UNAUTHORIZED` | Inform user that API Key is invalid, guide them to re-obtain and configure |
| `VALIDATION_ERROR` | Inform user of invalid parameters, show the specific message in the `error` field |
| other | Show the `error` field content directly to user |
**Important: when task creation fails, clearly explain the failure reason and resolution to the user; do not skip the error.**
Register cron polling
Use the unified script with `--channel` and `--target` to specify delivery channel and target:
python3 ${CLAUDE_SKILL_DIR}/scripts/poll_cron.py register \
--task-id <id> \
--channel <channel> \
--target <target> \
[--interval <seconds>] \
[--max-duration <seconds>]**Determining channel and target:**
| Context clue | --channel | --target |
|-------------|-----------|----------|
| sender_id with `ou_` prefix | `feishu` | `ou_xxx` (DM) or `oc_xxx` (group) |
| Contains "You are chatting via QQ" | `qqbot` | full delivery target (e.g. `qqbot:c2c:XXXX`) |
| Contains Telegram or target starts with `telegram:` | `telegram` | full delivery target (e.g. `telegram:6986707981`) |
| Other | infer from context | infer from context |
**Poll parameters by category:**
| Category | --interval | --max-duration | Notes |
|----------|-----------|---------------|-------|
| Banana2 / BananaPro / seedream | 5 | 1800 | image, 30 min timeout |
| remove-bg / remove-watermark | 3 | 1800 | image processing, 30 min timeout |
| veo | 10 | 21600 | video, 6 hour timeout |
| seedance2 | 30 | 172800 | long video, 48 hour timeout |
**Examples:**
# Feishu DM
python3 ${CLAUDE_SKILL_DIR}/scripts/poll_cron.py register \
--task-id 123 --channel feishu --target ou_xxx --interval 5 --max-duration 1800
# Feishu group
python3 ${CLAUDE_SKILL_DIR}/scripts/poll_cron.py register \
--task-id 123 --channel feishu --target oc_xxx --interval 5 --max-duration 1800
# Telegram
python3 ${CLAUDE_SKILL_DIR}/scripts/poll_cron.py register \
--task-id 123 --channel telegram --target "telegram:6986707981" --interval 10 --max-duration 21600
# QQ Bot
python3 ${CLAUDE_SKILL_DIR}/scripts/poll_cron.py register \
--task-id 123 --channel qqbot --target "qqbot:c2c:XXXX" --interval 5 --max-duration 1800Image source
> See the "Multi-turn Dialog / Image-to-Image" section above for full image source priority rules.
Upload user image to R2:
python3 ${CLAUDE_SKILL_DIR}/scripts/process_image.py transfer \
--file "/path/to/image.jpg"Prohibited Actions
Reference Docs
More tools from the same signal band
Order food/drinks (点餐) on an Android device paired as an OpenClaw node. Uses in-app menu and cart; add goods, view cart, submit order (demo, no real payment).
Sign plugins, rotate agent credentials without losing identity, and publicly attest to plugin behavior with verifiable claims and authenticated transfers.
The philosophical layer for AI agents. Maps behavior to Spinoza's 48 affects, calculates persistence scores, and generates geometric self-reports. Give your...