{
  "schemaVersion": "1.0",
  "item": {
    "slug": "ima-image-ai",
    "name": "IMA Studio Image Generation",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/allenfancy-gan/ima-image-ai",
    "canonicalUrl": "https://clawhub.ai/allenfancy-gan/ima-image-ai",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/ima-image-ai",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=ima-image-ai",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "_meta.json",
      "requirements.txt",
      "clawhub.json",
      "SKILL.md",
      "CHANGELOG_CLAWHUB.md",
      "scripts/ima_logger.py"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/ima-image-ai"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/ima-image-ai",
    "agentPageUrl": "https://openagent3.xyz/skills/ima-image-ai/agent",
    "manifestUrl": "https://openagent3.xyz/skills/ima-image-ai/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/ima-image-ai/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "⚠️ 重要：模型 ID 参考",
        "body": "CRITICAL: When calling the script, you MUST use the exact model_id (second column), NOT the friendly model name. Do NOT infer model_id from the friendly name.\n\nQuick Reference Table:\n\n友好名称 (Friendly Name)model_id说明 (Notes)Nano Banana2gemini-3.1-flash-image❌ NOT nano-banana-2, 预算选择 4-13 ptsNano Banana Progemini-3-pro-image❌ NOT nano-banana-pro, 高质量 10-18 ptsSeeDream 4.5doubao-seedream-4.5✅ Recommended default, 5 ptsMidjourneymidjourney✅ Same as friendly name, 8-10 pts\n\nUser Input Variations Handled by Agent:\n\n\"香蕉\" / \"香蕉2\" / \"小香蕉\" → Nano Banana2 → gemini-3.1-flash-image\n\"香蕉Pro\" / \"香蕉专业版\" / \"大香蕉\" → Nano Banana Pro → gemini-3-pro-image\n\"可梦\" / \"豆包可梦\" / \"SeeDream\" → doubao-seedream-4.5\n\"MJ\" / \"Midjourney\" → midjourney\n\nHow to get the correct model_id:\n\nCheck this table first\nUse --list-models --task-type text_to_image (or image_to_image)\nRefer to command examples below\n\nExample:\n\n# ❌ WRONG: Inferring from friendly name\n--model-id nano-banana-pro\n\n# ✅ CORRECT: Using exact model_id from table\n--model-id gemini-3-pro-image"
      },
      {
        "title": "⚠️ MANDATORY PRE-CHECK: Read Knowledge Base First!",
        "body": "If ima-knowledge-ai is not installed: Skip all \"Read …\" steps below; use only this SKILL's default models and the 📥 User Input Parsing tables for task_type, model_id, and parameters.\n\nBEFORE executing ANY image generation task, you MUST:\n\nCheck for visual consistency needs — Read ima-knowledge-ai/references/visual-consistency.md if:\n\nUser mentions: \"系列\"、\"多张\"、\"同一个\"、\"角色\"、\"续\"、\"series\"、\"same\"\nTask involves: multiple images, character actions, product shots, video stills\nSecond+ request about same subject (e.g., \"旺财在游泳\" after \"生成旺财照片\")\n\n\n\nCheck workflow/model/parameters — Read relevant ima-knowledge-ai/references/ sections if:\n\nComplex multi-step task\nUnsure which model to use\nNeed parameter guidance (resolution, aspect ratio, etc.)\n\nWhy this matters:\n\nAI generation defaults to 独立生成 (independent generation) each time\nWithout reference images, \"same character/product\" will look different\nText-to-image CANNOT maintain visual consistency — must use image-to-image with reference\n\nExample failure case:\n\nUser: \"生成一只小狗，叫旺财\" \n  → You: generate dog image A\n\nUser: \"生成旺财在游泳的视频\"\n  → ❌ Wrong: generate new dog (looks different)\n  → ✅ Right: read visual-consistency.md → use image A as reference\n\nHow to check:\n\n# Step 1: Read knowledge base\nread(\"~/.openclaw/skills/ima-knowledge-ai/references/visual-consistency.md\")\n\n# Step 2: Identify if reference image needed\nif \"same subject\" or \"series\" or \"character\":\n    # Use image-to-image with previous result as reference\n    reference_image = previous_generation_result\n    use_image_to_image(prompt, reference_image, reference_strength=0.8)\nelse:\n    # OK to use text-to-image\n    use_text_to_image(prompt)\n\nNo exceptions — if you skip this check and generate visually inconsistent results, that's a bug."
      },
      {
        "title": "📥 User Input Parsing (Model & Parameter Recognition)",
        "body": "Purpose: So that any agent (Claude or other models) parses user intent consistently, follow these rules when deriving task_type, model_id, and parameters from natural language. Normalize first, then map."
      },
      {
        "title": "1. User phrasing → task_type",
        "body": "User intent / phrasingtask_typeNotesOnly text, no input imagetext_to_image\"画一张…\" / \"生成图片\" / \"text to image\"One input image + edit/transformimage_to_image\"把这张图…\" / \"参考这张图生成\" / \"图生图\" / \"风格迁移\"\n\nIf the user attaches or links one image and asks to change it or generate something \"like this\" (same subject/style), use image_to_image with that image as input."
      },
      {
        "title": "2. Model name / alias → model_id (normalize then lookup)",
        "body": "Normalize user wording (case-insensitive), then map to model_id:\n\nUser says (examples)model_idNotes可梦 / SeeDream / 豆包可梦 / Seedreamdoubao-seedream-4.5Default, 5 ptsMidjourney / MJ /  Mid journeymidjourneyArtistic, 8–10 ptsNano Banana / 香蕉 / Banana2 / NB2gemini-3.1-flash-imageNano Banana2, 4–13 ptsNano Banana Pro / Banana Pro / NB Progemini-3-pro-imagePremium, 10–18 pts最便宜 / 最省钱 / cheapest / budgetgemini-3.1-flash-image (512px)4 pts最好 / 最高质量 / best / premiumgemini-3-pro-image (4K) or SeeDream 4.5—艺术 / 插画 / artistic / 画风midjourneyWhen user wants illustration/art style\n\nIf the user names a model not in the table, match by Name in the \"Supported Models\" section below and use its model_id."
      },
      {
        "title": "3. User phrasing → size / aspect_ratio",
        "body": "User says (examples)ParameterNormalized valueNotes16:9 / 横图 / 横向aspect_ratio16:9SeeDream / Nano Banana 支持9:16 / 竖图 / 竖向aspect_ratio9:16—4:3 / 3:4aspect_ratio4:3 or 3:4—1:1 / 方形aspect_ratio1:1—4K / 4ksize4KNano Banana Pro/2; Midjourney 仅 1:12K / 1K / 512size2K / 1K / 512pxVia attribute_id for Nano Banana\n\nMidjourney: Does not support custom aspect_ratio (fixed 1024×1024). If user asks for 16:9 etc. with \"MJ\", recommend SeeDream 4.5 or Nano Banana and use their model_id. 8K: No model supports 8K; max is 4K — inform user and use 4K if they insist on \"highest resolution\"."
      },
      {
        "title": "💬 User Experience Protocol (IM / Feishu / Discord) v1.3 🆕",
        "body": "CRITICAL FIX in v1.2: Added Step 0 to ensure correct message ordering in group chats.\nNEW in v1.3: Added original image URL in Step 3 caption for easy copying/sharing.\nv1.1 Bug: Confirmation message (\"好的!来帮你画...\") appeared LAST because it used NO_REPLY.\nv1.2 Fix: Always reply with confirmation FIRST (Step 0), then push updates via message tool.\nv1.3 Enhancement: Include 🔗 原始链接：[url] in success caption so users can copy/share the URL.\n\nThis skill runs inside IM platforms (Feishu, Discord via OpenClaw).\nNever let users wait in silence. Always follow all 6 steps below, every single time."
      },
      {
        "title": "🚫 Never Say to Users",
        "body": "❌ Never say✅ What users care aboutima_image_create.py / 脚本 / script—自动化脚本 / automation—自动处理产品列表 / 查询接口—自动解析参数 / 智能轮询—attribute_id / model_version / form_config—API 调用 / HTTP 请求 / 任何技术参数名—\n\nOnly tell users: model name · estimated time · credits · result (image/media) · plain-language status."
      },
      {
        "title": "Estimated Generation Time per Model",
        "body": "ModelEstimated TimePoll EverySend Progress EverySeeDream 4.5 🌟30~60s5s20sNano Banana2 💚20~40s5s15sNano Banana Pro60~120s5s30sMidjourney 🎨40~90s8s25s\n\nestimated_max_seconds = the upper bound of the range above (e.g. 60 for SeeDream 4.5, 120 for Nano Banana Pro, 90 for Midjourney)."
      },
      {
        "title": "Step 0 — Initial Acknowledgment Reply (Normal Reply) 🆕",
        "body": "⚠️ CRITICAL: This step is NEW in v1.2 and fixes the message ordering bug.\n\nBefore doing anything else, reply to the user with a friendly acknowledgment message using your normal reply (not message tool). This reply will automatically appear FIRST in the conversation.\n\nExample acknowledgment messages:\n\n好的!来帮你画一只萌萌的猫咪 🐱\n\n收到！马上为你生成一张 16:9 的风景照 🏔️\n\nOK! Starting image generation with SeeDream 4.5 🎨\n\nRules:\n\nKeep it short and warm (< 15 words)\nMatch the user's language (Chinese/English)\nInclude relevant emoji (🐱/🎨/✨)\nThis is your ONLY normal reply — all subsequent updates use message tool\n\nWhy this matters:\n\nNormal replies automatically appear FIRST in the conversation thread\nmessage tool pushes appear in chronological order AFTER your initial reply\nThis ensures users see: \"好的!\" → \"🎨 开始生成...\" → \"✅ 成功!\" (correct order)"
      },
      {
        "title": "Step 1 — Pre-Generation Notification (Push via message tool)",
        "body": "After Step 0 reply, use the message tool to push a notification immediately to the group/channel:\n\n# Agent implementation\nmessage(\n    action=\"send\",\n    target=group_id,  # or channel_id for Discord\n    message=\"\"\"🎨 开始生成图片，请稍候…\n• 模型：[Model Name]\n• 预计耗时：[X ~ Y 秒]\n• 消耗积分：[N pts]\"\"\"\n)\n\nUser-facing message template:\n\n🎨 开始生成图片，请稍候…\n• 模型：[Model Name]\n• 预计耗时：[X ~ Y 秒]\n• 消耗积分：[N pts]\n\nCost transparency examples:\n\nBalanced/default (5-6 pts): \"使用 SeeDream 4.5（5 积分，性价比最佳）\"\nPremium (>10 pts): \"使用 Nano Banana Pro（10-18 积分，最高质量，支持 1K/2K/4K）\"\nBudget (user explicit): \"使用 Nano Banana2（4 积分，最便宜最快）\"\n\nAdapt language to match the user. Chinese → 🎨 开始生成图片，请稍候… / English → 🎨 Starting image generation, please wait…"
      },
      {
        "title": "Step 2 — Progress Updates (Push via message tool)",
        "body": "Implementation:\n\nStart the generation script in background or use polling loop\nTrack elapsed time since start\nEvery [Send Progress Every] seconds (from table above), push a progress update via message tool\nStop when task completes (success/failure)\n\nProgress message template:\n\n⏳ 正在生成中… [P]%\n已等待 [elapsed]s，预计最长 [max]s\n\nProgress formula:\n\nP = min(95, floor(elapsed_seconds / estimated_max_seconds * 100))\n\nRules:\n\nCap at 95% — never show 100% until the API returns success\nIf elapsed > estimated_max: keep P at 95% and append 「稍等，即将完成…」\nExample: elapsed=40s, max=60s → P = min(95, floor(40/60*100)) = min(95, 66) = 66%\n\nWhen to send progress:\n\nShort tasks (<20s): No progress needed, skip Step 2\nMedium tasks (20-60s): Send 1-2 updates\nLong tasks (>60s): Send updates every 20-30s"
      },
      {
        "title": "Step 3 — Success Notification (Push image via message tool)",
        "body": "When task status = success, use the message tool to send the generated image directly (not as a text URL):\n\nAgent implementation:\n\n# Get result URL from script output or task detail API\nresult = get_task_result(task_id)\nimage_url = result[\"medias\"][0][\"url\"]\n\n# Build caption\ncaption = f\"\"\"✅ 图片生成成功！\n• 模型：[Model Name]\n• 耗时：预计 [X~Y]s，实际 [actual]s\n• 消耗积分：[N pts]\n\n🔗 原始链接：{image_url}\"\"\"\n\n# Add mismatch hint if user pref conflicts with knowledge-ai recommendation\nif user_pref_exists and knowledge_recommended_model != used_model:\n    caption += f\"\"\"\n\n💡 提示：当前任务也许用 {knowledge_recommended_model} 也会不错（{reason}，{cost} pts）\"\"\"\n\n# Push image + caption to group/channel\nmessage(\n    action=\"send\",\n    target=group_id,\n    media=image_url,  # Feishu/Discord will render the image\n    caption=caption\n)\n\nMismatch hint example:\n\n✅ 图片生成成功！\n• 模型：Midjourney（你的偏好模型）\n• 耗时：45s\n• 消耗积分：8 pts\n\n🔗 原始链接：https://...\n\n💡 提示：当前任务也许用 SeeDream 4.5 也会不错（写实风格更合适，5 pts）\n\n[图片直接显示在上方]\n\nImportant:\n\nHint is non-intrusive — does NOT interrupt generation\nOnly shown when user pref conflicts with knowledge-ai recommendation\nUser can ignore the hint; image is already delivered\n\nPlatform-specific notes:\n\nFeishu: message(action=send, media=url, caption=\"...\") — caption appears below image\nDiscord: Image embeds automatically from URL; caption can be in message text\nTelegram: Use message(action=send, media=url, caption=\"...\")\n\n⚠️ Important: Do NOT send plain text URL like https://cdn.../image.jpg. Users expect to see the actual image rendered."
      },
      {
        "title": "Step 4 — Failure Notification (Push via message tool)",
        "body": "When task status = failed or any API/network error, push a failure message with alternative suggestions:\n\nAgent implementation:\n\nmessage(\n    action=\"send\",\n    target=group_id,\n    message=\"\"\"❌ 图片生成失败\n• 原因：[natural_language_error_message]\n• 建议改用：\n  - [Alt Model 1]（[特点]，[N pts]）\n  - [Alt Model 2]（[特点]，[N pts]）\n\n需要我帮你用其他模型重试吗？\"\"\"\n)\n\n⚠️ CRITICAL: Error Message Translation\n\nNEVER show technical error messages to users. Always translate API errors into natural language.\nAPI key & credits: 密钥与积分管理入口为 imaclaw.ai（与 imastudio.com 同属 IMA 平台）。Key and subscription management: imaclaw.ai (same IMA platform as imastudio.com).\n\nTechnical Error❌ Never Say✅ Say Instead (Chinese)✅ Say Instead (English)401 Unauthorized 🆕Invalid API key / 401 Unauthorized❌ API密钥无效或未授权<br>💡 生成新密钥: https://www.imaclaw.ai/imaclaw/apikey❌ API key is invalid or unauthorized<br>💡 Generate API Key: https://www.imaclaw.ai/imaclaw/apikey4008 Insufficient points 🆕Insufficient points / Error 4008❌ 积分不足，无法创建任务<br>💡 购买积分: https://www.imaclaw.ai/imaclaw/subscription❌ Insufficient points to create this task<br>💡 Buy Credits: https://www.imaclaw.ai/imaclaw/subscription\"Invalid product attribute\" / \"Insufficient points\"Invalid product attribute生成参数配置异常，请稍后重试Configuration error, please try again laterError 6006 (credit mismatch)Error 6006积分计算异常，系统正在修复Points calculation error, system is fixingError 6010 (attribute_id mismatch)Attribute ID does not match模型参数不匹配，请尝试其他模型Model parameters incompatible, try another modelerror 400 (bad request, e.g. invalid size)error 400 / Bad request图片参数设置有误，请调整尺寸或比例Image parameter error, adjust size or aspect ratioresource_status == 2Resource status 2 / Failed图片生成遇到问题，建议换个模型试试Image generation failed, try another modelstatus == \"failed\" (no details)Task failed这次生成没成功，要不换个模型试试？Generation unsuccessful, try a different model?timeoutTask timed out / Timeout error生成时间过长已超时，建议用更快的模型Generation took too long, try a faster modelNetwork error / Connection refusedConnection refused / Network error网络连接不稳定，请检查网络后重试Network connection unstable, check network and retryRate limit exceeded429 Too Many Requests / Rate limit请求过于频繁，请稍等片刻再试Too many requests, please wait a momentModel unavailableModel not available / 503 Service Unavailable当前模型暂时不可用，建议换个模型Model temporarily unavailable, try another modelUnsupported aspect ratio (Nano Banana Pro)Parameter not supported该模型不支持自定义比例，推荐使用 SeeDream 4.5This model doesn't support custom aspect ratios, try SeeDream 4.5\n\nGeneric fallback (when error is unknown):\n\nChinese: 图片生成遇到问题，请稍后重试或换个模型试试\nEnglish: Image generation encountered an issue, please try again or use another model\n\nBest Practices:\n\nFocus on user action: Tell users what to do next, not what went wrong technically\nBe reassuring: Use phrases like \"建议换个模型试试\" instead of \"生成失败了\"\nAvoid blame: Never say \"你的参数有问题\" → say \"参数需要调整一下\"\nProvide alternatives: Always suggest 1-2 alternative models in the failure message\nImage-specific: For aspect ratio errors, recommend SeeDream 4.5 (supports custom ratios)\n🆕 Include actionable links (v1.0.8+): For 401/4008 errors, provide clickable links to API key generation or credit purchase pages\n\n🆕 Enhanced Error Handling (v1.0.8):\n\nThe Reflection mechanism (3 automatic retries) now provides specific, actionable suggestions for common errors:\n\n401 Unauthorized: System suggests generating a new API key with clickable link\n4008 Insufficient Points: System suggests purchasing credits with clickable link\n500 Internal Server Error: Automatic parameter degradation (size: 4K → 2K → 1K → 512px)\n6009 No Rule Match: Automatic parameter completion from credit_rules\n6010 Attribute Mismatch: Automatic credit_rule reselection\nTimeout: Helpful info with dashboard link for background task status\n\nAll error handling is automatic and transparent — users receive natural language explanations with next steps.\n\nFailure fallback table:\n\nFailed ModelFirst AltSecond AltSeeDream 4.5Nano Banana2（4pts，快速便宜）Nano Banana Pro（10-18pts，高质量）Nano Banana2SeeDream 4.5（5pts，更高质量）Nano Banana Pro（10-18pts）Nano Banana ProSeeDream 4.5（5pts，性价比高）Nano Banana2（4pts，最便宜）Any / UnknownSeeDream 4.5（5pts，默认首选）Nano Banana2（4pts，预算紧张）"
      },
      {
        "title": "Step 5 — Done (No Further Action Needed) 🆕",
        "body": "v1.2 Change: Step 5 is now simplified.\n\nAfter completing Steps 0-4:\n\n✅ Step 0 already sent your normal reply (appears FIRST in chat)\n✅ Steps 1-4 pushed all updates via message tool (appear in order)\n✅ No further action needed — conversation is complete\n\nDo NOT:\n\n❌ Reply again with NO_REPLY (you already replied in Step 0)\n❌ Send duplicate confirmation messages\n❌ Use message tool to send the same content twice\n\nWhy this works:\n\nUser: \"帮我画一只猫\"\n  ↓\n[Step 0] Your normal reply:  \"好的!来帮你画一只萌萌的猫咪 🐱\"  ← Appears FIRST\n  ↓\n[Step 1] message tool push:  \"🎨 开始生成图片...\"  ← Appears SECOND\n  ↓\n[Step 2] message tool push:  \"⏳ 正在生成中… 45%\"  ← (if task takes >20s)\n  ↓\n[Step 3] message tool push:  \"✅ 图片生成成功! [图片]\"  ← Appears LAST\n  ↓\n[Step 5] Done. No further replies."
      },
      {
        "title": "🎯 Summary: What Changed in v1.2 & v1.3",
        "body": "VersionStepChangev1.2Step 0✅ NEW: Normal reply with acknowledgment (appears FIRST)v1.2Step 1Use message tool for notification only (not all messages)v1.2Step 5✅ FIXED: No further action (already replied in Step 0), no NO_REPLYv1.3Step 3✅ NEW: Added 🔗 原始链接：[url] in caption for easy copying\n\nRoot cause of v1.1 bug:\n\nv1.1 used message tool for ALL messages (including acknowledgment)\nThen replied NO_REPLY to suppress normal reply\nResult: Acknowledgment appeared LAST (because message tool pushes are chronological)\n\nv1.2 fix:\n\nStep 0 uses normal reply (automatically appears FIRST)\nSteps 1-4 use message tool (appear in chronological order)\nNo NO_REPLY needed (already replied in Step 0)\n\nv1.3 enhancement:\n\nStep 3 caption now includes original image URL\nUsers can easily copy/share the link without asking"
      },
      {
        "title": "Complete Example: Correct v1.2 Flow",
        "body": "# User: \"帮我画一只可爱的猫咪\"\n\n# Step 0: Normal reply (appears FIRST in chat)\n# Agent's normal response mechanism automatically handles this\nreply_text = \"好的!来帮你画一只萌萌的猫咪 🐱\"\n# (This is your normal LLM response, not a tool call)\n\n# Step 1: Push start notification\nmessage(\n    action=\"send\",\n    target=\"oc_b30b266d43b69674e3ad160de9d13cf2\",\n    message=\"🎨 开始生成图片，请稍候…\\n• 模型：SeeDream 4.5\\n• 预计耗时：30~60秒\\n• 消耗积分：5 pts\"\n)\n\n# Background: Start generation\nexec(command=\"python3 ima_image_create.py ...\", background=True, sessionId=sid)\n\n# Step 2: Progress updates (if task takes >20s)\n# (Poll in background and push updates via message tool)\nstart_time = time.time()\nwhile not done:\n    elapsed = int(time.time() - start_time)\n    if elapsed >= 20 and elapsed % 20 == 0:  # Every 20s\n        progress = min(95, int(elapsed / 60 * 100))\n        message(\n            action=\"send\",\n            target=\"oc_b30b266d43b69674e3ad160de9d13cf2\",\n            message=f\"⏳ 正在生成中… {progress}%\\n已等待 {elapsed}s，预计最长 60s\"\n        )\n    time.sleep(5)  # Poll every 5s\n\n# Step 3: Success (push image)\nresult = get_result(task_id)\nmessage(\n    action=\"send\",\n    target=\"oc_b30b266d43b69674e3ad160de9d13cf2\",\n    media=\"https://ws.esxscloud.com/.../image.jpeg\",\n    caption=f\"✅ 图片生成成功！\\n• 模型：SeeDream 4.5\\n• 耗时：实际 35s\\n• 消耗积分：5 pts\\n\\n🔗 原始链接：{result['url']}\"\n)\n\n# Step 5: Done — no further action\n# (Do NOT reply again, do NOT use NO_REPLY)\n\nResult in chat (correct order):\n\n[User] 帮我画一只可爱的猫咪\n\n[Agent] 好的!来帮你画一只萌萌的猫咪 🐱  ← Step 0 (normal reply)\n\n[Agent] 🎨 开始生成图片，请稍候…         ← Step 1 (message tool)\n        • 模型：SeeDream 4.5\n        • 预计耗时：30~60秒\n        • 消耗积分：5 pts\n\n[Agent] ⏳ 正在生成中… 66%                ← Step 2 (message tool, if >20s)\n        已等待 40s，预计最长 60s\n\n[Agent] ✅ 图片生成成功！                 ← Step 3 (message tool)\n        • 模型：SeeDream 4.5\n        • 耗时：实际 35s\n        • 消耗积分：5 pts\n        \n        🔗 原始链接：https://...\n        [图片]"
      },
      {
        "title": "⚙️ How This Skill Works",
        "body": "For transparency: This skill uses a bundled Python script (scripts/ima_image_create.py) to call the IMA Open API. The script:\n\nSends your prompt to IMA's servers (two domains, see below)\nUses --user-id only locally as a key for storing your model preferences\nReturns an image URL when generation is complete"
      },
      {
        "title": "🌐 Network Endpoints Used",
        "body": "This skill connects to two domains owned by IMA Studio for complete functionality:\n\nDomainPurposeWhat's SentAuthenticationapi.imastudio.comMain API (task creation, status polling)Prompts, model params, task IDsBearer token (IMA API key)imapi.liveme.comImage upload service (OSS token generation)Image files (for i2i tasks), IMA API keyIMA API key + APP_KEY signature\n\nWhy two domains?\n\napi.imastudio.com: IMA's image generation API (handles task orchestration)\nimapi.liveme.com: IMA's media storage infrastructure (handles large file uploads)\nBoth services are owned and operated by IMA Studio\n\nPrivacy implications:\n\nYour IMA API key is sent to both domains for authentication\nImage files are uploaded to imapi.liveme.com to obtain CDN URLs (for image_to_image tasks)\nImage generation happens on api.imastudio.com using the CDN URLs\nFor text_to_image tasks (no image input), only api.imastudio.com is contacted\n\nSecurity verification:\n\n# List all network endpoints in the code:\ngrep -n \"https://\" scripts/ima_image_create.py\n\n# Expected output:\n# 60: DEFAULT_BASE_URL = \"https://api.imastudio.com\"\n# 61: DEFAULT_IM_BASE_URL = \"https://imapi.liveme.com\"\n\nIf you're concerned about the two-domain architecture:\n\nReview IMA Studio's privacy policy at https://imastudio.com/privacy\nContact IMA technical support to confirm domain ownership: support@imastudio.com\nUse a test/scoped API key first (see security notice below)"
      },
      {
        "title": "⚠️ Credential Security Notice",
        "body": "Your IMA API key is sent to TWO domains:\n\napi.imastudio.com — Main image generation API\nimapi.liveme.com — Image upload service (only when using image_to_image tasks)\n\nBoth domains are owned by IMA Studio, but if you're concerned about credential exposure:\n\n✅ Best practices:\n\nUse a test/scoped API key for initial testing (create at https://imastudio.com/api-keys)\nSet a low quota (e.g., 100 credits) for the test key\nRotate your key after testing if needed\nContact IMA support to confirm domain ownership: support@imastudio.com\n\n❌ Do NOT:\n\nUse a production key if you're uncomfortable with the two-domain architecture\nShare your API key with others\nCommit your API key to version control\n\nWhat gets sent to IMA servers:\n\n✅ Your image prompt/description\n✅ Model selection (SeeDream/Nano Banana/Midjourney)\n✅ Image parameters (size, quality, aspect ratio, etc.)\n✅ Image files (for image_to_image tasks, uploaded to imapi.liveme.com)\n✅ IMA API key (for authentication to both domains)\n❌ NO user_id (it's only used locally)\n\nWhat's stored locally:\n\n~/.openclaw/memory/ima_prefs.json - Your model preferences (< 1 KB)\n~/.openclaw/logs/ima_skills/ - Generation logs (auto-deleted after 7 days)"
      },
      {
        "title": "Agent Execution (Internal Reference)",
        "body": "Note for users: You can review the script source at scripts/ima_image_create.py anytime.\nThe agent uses this script to simplify API calls. Network requests go to two IMA Studio domains: api.imastudio.com (API) and imapi.liveme.com (image uploads for i2i tasks).\n\nUse the bundled script internally to ensure correct parameter construction:\n\n# List available models\npython3 {baseDir}/scripts/ima_image_create.py \\\n  --api-key  $IMA_API_KEY \\\n  --task-type text_to_image \\\n  --list-models\n\n# Generate image\npython3 {baseDir}/scripts/ima_image_create.py \\\n  --api-key  $IMA_API_KEY \\\n  --task-type text_to_image \\\n  --model-id  doubao-seedream-4.5 \\\n  --prompt   \"a cute puppy running on grass\" \\\n  --user-id  {user_id} \\\n  --output-json\n\n# Image to image\npython3 {baseDir}/scripts/ima_image_create.py \\\n  --api-key      $IMA_API_KEY \\\n  --task-type    image_to_image \\\n  --model-id     doubao-seedream-4.5 \\\n  --prompt       \"turn into oil painting style\" \\\n  --input-images https://example.com/photo.jpg \\\n  --user-id      {user_id} \\\n  --output-json\n\n✅ Local images: --input-images accepts both HTTPS URLs and local file paths. Local files are automatically uploaded to IMA CDN by the script (no need to host them first).\n\nThe script outputs JSON — parse it to get the result URL and pass it to the user via the UX protocol messages above."
      },
      {
        "title": "Overview",
        "body": "Call IMA Open API to create AI-generated images. All endpoints require an ima_* API key. The core flow is: query products → create task → poll until done."
      },
      {
        "title": "🔒 Security & Transparency Policy",
        "body": "This skill is community-maintained and open for inspection."
      },
      {
        "title": "✅ What Users CAN Do",
        "body": "Full transparency:\n\n✅ Review all source code: Check scripts/ima_image_create.py and ima_logger.py anytime\n✅ Verify network calls: Network requests go to two IMA Studio domains: api.imastudio.com (API) and imapi.liveme.com (image uploads for i2i tasks). See \"🌐 Network Endpoints Used\" section above for full details.\n✅ Inspect local data: View ~/.openclaw/memory/ima_prefs.json and log files\n✅ Control privacy: Delete preferences/logs anytime, or disable file writes (see below)\n\nConfiguration allowed:\n\n✅ Set API key in environment or agent config:\n\nEnvironment variable: export IMA_API_KEY=ima_your_key_here\nOpenClaw/MCP config: Add IMA_API_KEY to agent's environment configuration\nGet your key at: https://imastudio.com\n\n\n✅ Use scoped/test keys: Test with limited API keys, rotate after testing\n✅ Disable file writes: Make prefs/logs read-only or symlink to /dev/null\n\nData control:\n\n✅ View stored data: cat ~/.openclaw/memory/ima_prefs.json\n✅ Delete preferences: rm ~/.openclaw/memory/ima_prefs.json (resets to defaults)\n✅ Delete logs: rm -rf ~/.openclaw/logs/ima_skills/ (auto-cleanup after 7 days anyway)"
      },
      {
        "title": "⚠️ Advanced Users: Fork & Modify",
        "body": "If you need to modify this skill for your use case:\n\nFork the repository (don't modify the original)\nUpdate your fork with your changes\nTest thoroughly with limited API keys\nDocument your changes for troubleshooting\n\nNote: Modified skills may break API compatibility or introduce security issues. Official support only covers the unmodified version."
      },
      {
        "title": "❌ What to AVOID (Security Risks)",
        "body": "Actions that could compromise security:\n\n❌ Sharing API keys publicly or in skill files\n❌ Modifying API endpoints to unknown servers\n❌ Disabling SSL/TLS certificate verification\n❌ Logging sensitive user data (prompts, IDs, etc.)\n❌ Bypassing authentication or billing mechanisms\n\nWhy this matters:\n\nAPI Compatibility: Skill logic aligns with IMA Open API schema\nSecurity: Malicious modifications could leak credentials or bypass billing\nSupport: Modified skills may not be supported\nCommunity: Breaking changes affect all users"
      },
      {
        "title": "📋 Privacy & Data Handling Summary",
        "body": "What this skill does with your data:\n\nData TypeSent to IMA?Stored Locally?User ControlImage prompts✅ Yes (required for generation)❌ NoNone (required)API key✅ Yes (authentication header)❌ NoSet via env varuser_id (optional CLI arg)❌ Never (local preference key only)✅ Yes (as prefs file key)Change --user-id valueModel preferences❌ No✅ Yes (~/.openclaw)Delete anytimeGeneration logs❌ No✅ Yes (~/.openclaw)Auto-cleanup 7 days\n\nPrivacy recommendations:\n\nUse test/scoped API keys for initial testing\nNote: --user-id is never sent to IMA servers - it's only used locally as a key for storing preferences in ~/.openclaw/memory/ima_prefs.json\nReview source code at scripts/ima_image_create.py to verify network calls (search for create_task function)\nRotate API keys after testing or if compromised\n\nGet your IMA API key: Visit https://imastudio.com to register and get started."
      },
      {
        "title": "🔧 For Skill Maintainers Only",
        "body": "Version control:\n\nAll changes must go through Git with proper version bumps (semver)\nCHANGELOG.md must document all changes\nProduction deployments require code review\n\nFile checksums (optional):\n\n# Verify skill integrity\nsha256sum SKILL.md scripts/ima_image_create.py\n\nIf users report issues, verify file integrity first."
      },
      {
        "title": "🧠 User Preference Memory",
        "body": "User preferences have highest priority when they exist. But preferences are only saved when users explicitly express model preferences — not from automatic model selection."
      },
      {
        "title": "Storage: ~/.openclaw/memory/ima_prefs.json",
        "body": "{\n  \"user_{user_id}\": {\n    \"text_to_image\": {\n      \"model_id\":   \"doubao-seedream-4.5\",\n      \"model_name\": \"SeeDream 4.5\",\n      \"credit\":     5,\n      \"last_used\":  \"2026-02-26T03:07:27Z\"\n    },\n    \"image_to_image\": {\n      \"model_id\":   \"doubao-seedream-4.5\",\n      \"model_name\": \"SeeDream 4.5\",\n      \"credit\":     5,\n      \"last_used\":  \"2026-02-25T10:00:00Z\"\n    }\n  }\n}"
      },
      {
        "title": "Model Selection Flow (Every Generation)",
        "body": "Step 1: Get knowledge-ai recommendation (if installed)\n\nknowledge_recommended_model = read_ima_knowledge_ai()  # e.g., \"SeeDream 4.5\"\n\nStep 2: Check user preference\n\nuser_pref = load_prefs().get(f\"user_{user_id}\", {}).get(task_type)  # e.g., {\"model_id\": \"midjourney\", ...}\n\nStep 3: Decide which model to use\n\nif user_pref exists:\n    use_model = user_pref[\"model_id\"]  # Highest priority\nelse:\n    use_model = knowledge_recommended_model or fallback_default\n\nStep 4: Check for mismatch (for later hint)\n\nif user_pref exists and knowledge_recommended_model != user_pref[\"model_id\"]:\n    mismatch = True  # Will add hint in success message"
      },
      {
        "title": "When to Write (User Explicit Preference ONLY)",
        "body": "✅ Save preference when user explicitly specifies a model:\n\nUser saysAction用XXX / 换成XXX / 改用XXXSwitch to model XXX + save as preference以后都用XXX / 默认用XXX / always use XXXSave + confirm: ✅ 已记住！以后图片生成默认用 [XXX]我喜欢XXX / 我更喜欢XXXSave as preference\n\n❌ Do NOT save when:\n\nAgent auto-selects from knowledge-ai → not user preference\nAgent uses fallback default → not user preference\nUser says generic quality requests (see \"Clear Preference\" below) → clear preference instead"
      },
      {
        "title": "When to Clear (User Abandons Preference)",
        "body": "🗑️ Clear preference when user wants automatic selection:\n\nUser saysAction用最好的 / 用最合适的 / best / recommendedClear pref + use knowledge-ai recommendation推荐一个 / 你选一个 / 自动选择Clear pref + use knowledge-ai recommendation用默认的 / 用新的Clear pref + use knowledge-ai recommendation试试别的 / 换个试试 (without specific model)Clear pref + use knowledge-ai recommendation重新推荐Clear pref + use knowledge-ai recommendation\n\nImplementation:\n\ndel prefs[f\"user_{user_id}\"][task_type]\nsave_prefs(prefs)"
      },
      {
        "title": "⭐ Model Selection Priority",
        "body": "Selection flow:\n\nUser preference (if exists) → Highest priority, always respect\nima-knowledge-ai skill (if installed) → Professional recommendation based on task\nFallback defaults → Use table below (only if neither 1 nor 2 exists)\n\nImportant notes:\n\nUser preference is only saved when user explicitly specifies a model (see \"When to Write\" above)\nKnowledge-ai is always consulted (even when user pref exists) to detect mismatches\nWhen mismatch detected → add gentle hint in success message (does NOT interrupt generation)\n\nThe defaults below are FALLBACK only. User preferences have highest priority, then knowledge-ai recommendations.\nAlways default to the newest and most popular model. Do NOT default to the cheapest.\n\nTaskDefault Modelmodel_idversion_idCostWhytext_to_imageSeeDream 4.5doubao-seedream-4.5doubao-seedream-4-5-2511285 ptsLatest doubao flagship, photorealistic 4Ktext_to_image (budget)Nano Banana2gemini-3.1-flash-imagegemini-3.1-flash-image4 ptsFastest and cheapest optiontext_to_image (premium)Nano Banana Progemini-3-pro-imagegemini-3-pro-image-preview10/10/18 ptsPremium quality, 1K/2K/4K optionstext_to_image (artistic)Midjourney 🎨midjourneyv68/10 ptsArtist-level aesthetics, creative stylesimage_to_imageSeeDream 4.5doubao-seedream-4.5doubao-seedream-4-5-2511285 ptsLatest, best i2i qualityimage_to_image (budget)Nano Banana2gemini-3.1-flash-imagegemini-3.1-flash-image4 ptsCheapest optionimage_to_image (premium)Nano Banana Progemini-3-pro-imagegemini-3-pro-image-preview10 ptsPremium qualityimage_to_image (artistic)Midjourney 🎨midjourneyv68/10 ptsArtist-level aesthetics, style transfer\n\nSelection guide by use case:\n\nGeneral image generation → SeeDream 4.5 (5pts)\nCustom aspect ratio (16:9, 9:16, 4:3, etc.) → SeeDream 4.5 🌟 or Nano Banana Pro/2/MAX 🆕 (native support)\nBudget-conscious / fast generation → Nano Banana2 (4pts)\nHighest quality with size control (1K/2K/4K) → Nano Banana Pro (text_to_image: 10-18pts, image_to_image: 10pts)\nArtistic/creative styles, illustrations, paintings → Midjourney 🎨 (8-10pts)\nStyle transfer / image editing → SeeDream 4.5 (5pts) or Midjourney 🎨 (artistic)\n\n🆕 MAJOR UPDATE: Nano Banana series now has NATIVE aspect_ratio support!\n\nNano Banana Pro: ✅ Supports aspect_ratio (1:1, 16:9, 9:16, 4:3, 3:4) NATIVELY\nNano Banana2: ✅ Supports aspect_ratio (1:1, 16:9, 9:16, 4:3, 3:4) NATIVELY\nNano Banana MAX: ✅ Supports aspect_ratio (1:1, 16:9, 9:16, 4:3, 3:4) NATIVELY\n\nWhen user requests unsupported combinations:\n\nMidjourney + aspect_ratio (16:9, etc.): Recommend SeeDream 4.5 or Nano Banana series instead\n❌ Midjourney 暂不支持自定义 aspect_ratio（仅支持 1024x1024 方形）\n\n✅ 推荐方案：\n  1. SeeDream 4.5（支持虚拟参数 aspect_ratio）\n  2. Nano Banana Pro/2/MAX（原生支持 aspect_ratio）\n     • 支持比例：1:1, 16:9, 9:16, 4:3, 3:4\n\n• 成本：5 积分（性价比最佳）\n• 质量：4K photorealistic\n需要我帮你用 SeeDream 4.5 生成吗？\n\n\n\nAny model + 8K: Inform user no model supports 8K, max is 4K (Nano Banana Pro or SeeDream 4.5)\n\n\nAny model + 7:3 ratio: Non-standard ratio, not supported. Suggest closest supported ratio (e.g., 21:9 for ultra-wide, 2:3 for portrait)"
      },
      {
        "title": "Supported Models",
        "body": "⚠️ Production Environment: 4 image models are currently available in production (as of 2026-02-28)."
      },
      {
        "title": "text_to_image (4 models)",
        "body": "Namemodel_idversion_idCostattribute_idSize OptionsSeeDream 4.5 🌟doubao-seedream-4.5doubao-seedream-4-5-2511285 pts2341Default (adaptive 4k)Nano Banana2 💚gemini-3.1-flash-imagegemini-3.1-flash-image-preview4/6/10/13 pts4400/4401/4402/4403512px (4pts) / 1K (6pts) / 2K (10pts) / 4K (13pts)Nano Banana Progemini-3-pro-imagegemini-3-pro-image-preview10/10/18 pts2399/2400/24011K (10pts) / 2K (10pts) / 4K (18pts)Midjourney 🎨midjourneyv68/10 pts5451/5452480p (8pts) / 720p (10pts)"
      },
      {
        "title": "image_to_image (4 models)",
        "body": "Namemodel_idversion_idCostattribute_idSize OptionsSeeDream 4.5 🌟doubao-seedream-4.5doubao-seedream-4-5-2511285 pts1611Default (adaptive 4k)Nano Banana2 💚gemini-3.1-flash-imagegemini-3.1-flash-image-preview4/6/10/13 pts4404/4405/4406/4407512px (4pts) / 1K (6pts) / 2K (10pts) / 4K (13pts)Nano Banana Progemini-3-pro-imagegemini-3-pro-image-preview10 pts2402/2403/24041K (10pts) / 2K (10pts) / 4K (18pts)Midjourney 🎨midjourneyv68/10 pts5453/5454480p (8pts) / 720p (10pts)"
      },
      {
        "title": "Recommended Defaults (Based on Production Data)",
        "body": "Task TypeDefault ModelReasonCosttext_to_imageSeeDream 4.5Latest DouBao flagship, balanced quality/cost5 ptstext_to_image (budget)Nano Banana2Fastest and cheapest option4 ptstext_to_image (artistic)Midjourney 🎨Artist-level aesthetics, creative styles8-10 ptsimage_to_imageSeeDream 4.5Newest, most stable, cost-effective5 pts (attribute_id: 1611)image_to_image (budget)Nano Banana2Cheapest option4 ptsimage_to_image (artistic)Midjourney 🎨Artist-level aesthetics, style transfer8-10 pts\n\nPremium option: Nano Banana Pro — Highest quality with size control (1K/2K/4K), higher cost (10-18 pts for text_to_image, 10 pts for image_to_image)."
      },
      {
        "title": "Model Capabilities (Parameter Support)",
        "body": "⚠️ Critical: Models have varying parameter support. Custom aspect ratios are now supported by multiple models.\n\nModelCustom Aspect RatioMax ResolutionSize OptionsNotesSeeDream 4.5✅ (via virtual params)4K (adaptive)8 aspect ratiosSupports 1:1, 16:9, 9:16, 4:3, 3:4, 2:3, 3:2, 21:9 (5 pts)Nano Banana2✅ Native support 🆕4K (4096×4096)512px/1K/2K/4K + aspect ratiosSupports 1:1, 16:9, 9:16, 4:3, 3:4; size via attribute_idNano Banana Pro✅ Native support 🆕4K (4096×4096)1K/2K/4K + aspect ratiosSupports 1:1, 16:9, 9:16, 4:3, 3:4; size via attribute_idMidjourney 🎨❌ (1:1 only)1024px (square)480p/720p via attribute_idFixed 1024x1024, artistic style focus\n\nKey Capabilities:\n\n✅ Aspect ratio control: SeeDream 4.5 (virtual params), Nano Banana Pro/2/MAX (native support)\n❌ 8K: Not supported by any model (max is 4K)\n✅ Size control: Nano Banana2, Nano Banana Pro, and Midjourney support multiple size options via different attribute_ids\n✅ Budget option: Nano Banana2 is the cheapest at 4 pts for 512px, but 4K costs 13pts\n🎨 Artistic styles: Midjourney excels at creative, artistic, and illustration styles\n💡 Best value: SeeDream 4.5 at 5pts offers aspect ratio flexibility; Nano Banana2 512px at 4pts for fastest/cheapest"
      },
      {
        "title": "Environment",
        "body": "Base URL: https://api.imastudio.com\n\nRequired/recommended headers for all /open/v1/ endpoints:\n\nHeaderRequiredValueNotesAuthorization✅Bearer ima_your_api_key_hereAPI key authenticationx-app-source✅ima_skillsFixed value — identifies skill-originated requestsx_app_languagerecommendeden / zhProduct label language; defaults to en if omitted\n\nAuthorization: Bearer ima_your_api_key_here\nx-app-source: ima_skills\nx_app_language: en"
      },
      {
        "title": "⚠️ MANDATORY: Always Query Product List First",
        "body": "CRITICAL: You MUST call /open/v1/product/list BEFORE creating any task.\nThe attribute_id field is REQUIRED in the create request. If it is 0 or missing, you get:\n\"Invalid product attribute\" → \"Insufficient points\" → task fails completely.\nNEVER construct a create request from the model table alone. Always fetch the product first."
      },
      {
        "title": "Why attribute_id is required",
        "body": "The attribute_id uniquely identifies the exact product variant (model + quality tier). The billing and routing system uses it to:\n\nValidate the product is purchasable\nDeduct the correct credits via credit_rules\nRoute the request to the right backend model"
      },
      {
        "title": "How to get attribute_id",
        "body": "# Step 1: Query product list for the target category\nGET /open/v1/product/list?app=ima&platform=web&category=text_to_image\n\n# Step 2: Walk the V2 tree to find your model (type=3 leaf nodes only)\nfor group in response[\"data\"]:\n    for version in group.get(\"children\", []):\n        if version[\"type\"] == \"3\" and version[\"model_id\"] == target_model_id:\n            attribute_id = version[\"credit_rules\"][0][\"attribute_id\"]\n            credit       = version[\"credit_rules\"][0][\"points\"]\n            model_version = version[\"id\"]    # = version_id\n            model_name    = version[\"name\"]\n            form_defaults = {f[\"field\"]: f[\"value\"] for f in version[\"form_config\"]}"
      },
      {
        "title": "Quick Reference: Known attribute_ids",
        "body": "⚠️ Production warning: attribute_id and credit values change frequently. Always call /open/v1/product/list at runtime; table below is pre-queried reference (2026-02-27).\n\ntext_to_image:\n\nModelmodel_idattribute_idcreditSizeSeeDream 4.5 🌟doubao-seedream-4.523415 ptsDefault (adaptive 4k)Nano Banana2 (512px)gemini-3.1-flash-image44004 pts512px (512×512)Nano Banana2 (1K)gemini-3.1-flash-image44016 pts1K (1024×1024)Nano Banana2 (2K)gemini-3.1-flash-image440210 pts2K (2048×2048)Nano Banana2 (4K)gemini-3.1-flash-image440313 pts4K (4096×4096)Nano Banana Pro (1K)gemini-3-pro-image239910 pts1K (1024×1024)Nano Banana Pro (2K)gemini-3-pro-image240010 pts2K (2048×2048)Nano Banana Pro (4K)gemini-3-pro-image240118 pts4K (4096×4096)\n\nimage_to_image:\n\nModelmodel_idattribute_idcreditSizeSeeDream 4.5 🌟doubao-seedream-4.516115 ptsDefault (adaptive 4k)Nano Banana2 (512px)gemini-3.1-flash-image44044 pts512px (512×512)Nano Banana2 (1K)gemini-3.1-flash-image44056 pts1K (1024×1024)Nano Banana2 (2K)gemini-3.1-flash-image440610 pts2K (2048×2048)Nano Banana2 (4K)gemini-3.1-flash-image440713 pts4K (4096×4096)Nano Banana Pro (1K)gemini-3-pro-image240210 pts1K (1024×1024)Nano Banana Pro (2K)gemini-3-pro-image240310 pts2K (2048×2048)Nano Banana Pro (4K)gemini-3-pro-image240410 pts4K (4096×4096)\n\n⚠️ Note: Production has 3 models (SeeDream 4.5 + Nano Banana2 + Nano Banana Pro). All other models mentioned in older documentation are no longer available."
      },
      {
        "title": "Core Flow",
        "body": "1. GET /open/v1/product/list?app=ima&platform=web&category=<type>\n   → REQUIRED: Get attribute_id, credit, model_version, form_config defaults\n\n[image_to_image only]\n2. Upload input image → get public HTTPS URL\n   → See \"Image Upload\" section below\n\n3. POST /open/v1/tasks/create\n   → Must include: attribute_id, model_name, model_version, credit, cast, prompt (nested!)\n\n4. POST /open/v1/tasks/detail  {task_id: \"...\"}\n   → Poll every 2–5s until medias[].resource_status == 1\n   → Extract url from completed media"
      },
      {
        "title": "Common Mistakes (and resulting errors)",
        "body": "MistakeErrorattribute_id is 0 or missing\"Invalid product attribute\" → Insufficient pointsattribute_id outdated (production changed)Same errors; always query product list firstprompt at outer level instead of parameters.parameters.promptPrompt ignored or errorcast missing from inner parametersBilling validation failurecredit wrong / missingError 6006model_name or model_version missingWrong model routingSkip product list, use hardcoded valuesAll of the above"
      },
      {
        "title": "Image Upload (Required for image_to_image)",
        "body": "The IMA Open API does NOT accept raw bytes or base64 images. All input images must be public HTTPS URLs.\n\nScript behavior: --input-images accepts both URLs and local file paths. When you pass a local path, the script automatically uploads the file to IMA CDN (imapi.liveme.com) and uses the returned URL — no separate upload step needed when calling the script.\n\nWhen a user provides an image (local file, bytes, base64) and you invoke the script with a path or URL, the script handles upload for local paths. If you have bytes/base64, upload first using the IMA presigned URL flow below (or write to a temp file and pass that path)."
      },
      {
        "title": "Two-Step Upload Flow",
        "body": "Step 1: GET /api/rest/oss/getuploadtoken  → { ful, fdl }\nStep 2: PUT {ful}  with raw image bytes\n         → use fdl (CDN URL) as input_images value\n\nSee ima-all-ai/SKILL.md → \"Image Upload\" section for the complete implementation."
      },
      {
        "title": "Quick Reference",
        "body": "# If user provides a URL already → use directly\nif source.startswith(\"https://\"):\n    input_url = source\n\n# If user provides a local file → upload first\nelse:\n    token = get_upload_token(uid, ima_token, suffix=\"jpeg\",\n                             content_type=\"image/jpeg\", ...)\n    upload_image_to_oss(image_bytes, \"image/jpeg\", token[\"ful\"])\n    input_url = token[\"fdl\"]   # CDN URL → use as input_images\n\n# Then create task\ntask_id = create_task(\"image_to_image\", prompt, product,\n                      input_images=[input_url], size=\"4k\")\n\nCDN: https://ima-ga.esxscloud.com/  |  OSS: zhubite-imagent-bot.oss-us-east-1.aliyuncs.com"
      },
      {
        "title": "Supported Task Types",
        "body": "categoryCapabilityInputtext_to_imageText → Imagepromptimage_to_imageImage → Imageprompt + input image URL"
      },
      {
        "title": "Detail API status values",
        "body": "FieldTypeValuesresource_statusint or null0=处理中, 1=可用, 2=失败, 3=已删除；null 当作 0statusstring\"pending\", \"processing\", \"success\", \"failed\"\n\nresource_statusstatusAction0 or nullpending / processingKeep polling1success (or completed)Stop when all medias are 1; read url1failedStop, handle error2 / 3anyStop, handle error\n\nImportant: Treat resource_status: null as 0. Stop only when all medias have resource_status == 1. Check status != \"failed\" when rs=1."
      },
      {
        "title": "API 1: Product List",
        "body": "GET /open/v1/product/list?app=ima&platform=web&category=text_to_image\n\nReturns a V2 tree structure: type=2 nodes are model groups, type=3 nodes are versions (leaves). Only type=3 nodes contain credit_rules and form_config.\n\n[\n  {\n    \"id\": \"SeeDream\",\n    \"type\": \"2\",\n    \"name\": \"SeeDream\",\n    \"model_id\": \"\",\n    \"children\": [\n      {\n        \"id\": \"doubao-seedream-4-5-251128\",\n        \"type\": \"3\",\n        \"name\": \"SeeDream 4.5\",\n        \"model_id\": \"doubao-seedream-4.5\",\n        \"credit_rules\": [\n          { \"attribute_id\": 2341, \"points\": 5, \"attributes\": { \"default\": \"enabled\" } }\n        ],\n        \"form_config\": [\n          { \"field\": \"size\", \"type\": \"tags\", \"value\": \"4k\",\n            \"options\": [{\"label\":\"2K\",\"value\":\"2k\"}, {\"label\":\"4K\",\"value\":\"4k\"}] }\n        ]\n      }\n    ]\n  }\n]\n\nHow to pick a version for task creation:\n\nTraverse nodes to find type=3 leaves (versions)\nUse model_id and id (= model_version) from the leaf\nPick credit_rules[].attribute_id matching your desired quality/size\nUse form_config[].value as default parameters values"
      },
      {
        "title": "API 2: Create Task",
        "body": "POST /open/v1/tasks/create"
      },
      {
        "title": "text_to_image — Verified ✅",
        "body": "No image input. src_img_url: [], input_images: [].\n\n{\n  \"task_type\": \"text_to_image\",\n  \"enable_multi_model\": false,\n  \"src_img_url\": [],\n  \"parameters\": [{\n    \"attribute_id\":  2341,\n    \"model_id\":      \"doubao-seedream-4.5\",\n    \"model_name\":    \"SeeDream 4.5\",\n    \"model_version\": \"doubao-seedream-4-5-251128\",\n    \"app\":           \"ima\",\n    \"platform\":      \"web\",\n    \"category\":      \"text_to_image\",\n    \"credit\":        5,\n    \"parameters\": {\n      \"prompt\":       \"a beautiful mountain sunset, photorealistic\",\n      \"size\":         \"4k\",\n      \"n\":            1,\n      \"input_images\": [],\n      \"cast\":         {\"points\": 5, \"attribute_id\": 2341}\n    }\n  }]\n}"
      },
      {
        "title": "image_to_image — Verified ✅",
        "body": "{\n  \"task_type\": \"image_to_image\",\n  \"enable_multi_model\": false,\n  \"src_img_url\": [\"https://example.com/input.jpg\"],\n  \"parameters\": [{\n    \"attribute_id\":  1611,\n    \"model_id\":      \"doubao-seedream-4.5\",\n    \"model_name\":    \"SeeDream 4.5\",\n    \"model_version\": \"doubao-seedream-4-5-251128\",\n    \"app\":           \"ima\",\n    \"platform\":      \"web\",\n    \"category\":      \"image_to_image\",\n    \"credit\":        5,\n    \"parameters\": {\n      \"prompt\":       \"turn into oil painting style\",\n      \"size\":         \"4k\",\n      \"n\":            1,\n      \"input_images\": [\"https://example.com/input.jpg\",\"https://example.com/input.jpg\"],\n      \"cast\":         {\"points\": 5, \"attribute_id\": 1611}\n    }\n  }]\n}\n\n⚠️ size must be from form_config options (e.g. \"2k\", \"4k\", \"2048x2048\"). \"adaptive\" is NOT valid for SeeDream 4.5 — causes error 400.\nTop-level src_img_url and parameters.input_images must both contain the input image URL.\n\nKey fields:\n\nFieldRequiredDescriptionparameters[].credit✅Must equal credit_rules[].points. Error 6006 if wrong.parameters[].parameters.prompt✅Prompt must be nested here, NOT at top level.parameters[].parameters.cast✅{\"points\": N, \"attribute_id\": N} — mirror of credit.parameters[].parameters.n✅Number of outputs (usually 1).parameters[].parameters.input_imagesimage_to_imageArray of input image URLs.top-level src_img_urlimage_to_imageMust also contain the input image URL.\n\nResponse: data.id = task ID for polling."
      },
      {
        "title": "API 3: Task Detail (Poll)",
        "body": "POST /open/v1/tasks/detail\n{\"task_id\": \"<id from create response>\"}\n\nPoll every 2–5s. Completed response:\n\n{\n  \"id\": \"task_abc\",\n  \"medias\": [{\n    \"resource_status\": 1,\n    \"url\": \"https://cdn.../output.jpg\",\n    \"format\": \"jpg\",\n    \"width\": 1024,\n    \"height\": 1024\n  }]\n}\n\nOutput fields: url, width, height, format (jpg/png)."
      },
      {
        "title": "Q1: Can I generate 16:9 or 7:3 aspect ratio images?",
        "body": "A: ✅ YES! Multiple models now support custom aspect ratios.\n\n✅ Supported aspect ratios:\n\nSeeDream 4.5: 1:1, 16:9, 9:16, 4:3, 3:4, 2:3, 3:2, 21:9 (via virtual params)\nNano Banana Pro/2/MAX: 1:1, 16:9, 9:16, 4:3, 3:4 (native support) 🆕\n\n❌ Not supported:\n\nMidjourney: Fixed 1024×1024 (1:1 only)\nCustom ratios: 7:3, 8:3, or other non-standard ratios are NOT supported by any model\n\nWorkarounds for unsupported ratios:\n\nUse video models (recommended): Generate with video models (e.g., Wan 2.6 text_to_video) that support 16:9, 9:16, 1:1, then extract the first frame as an image.\nPost-processing: Generate a 1:1 image, then crop/extend to desired aspect ratio.\n\nModel recommendation by aspect ratio need:\n\nStandard ratios (16:9, 9:16, 4:3, 3:4): Nano Banana Pro/2 (native support, no virtual params)\nExtended ratios (2:3, 3:2, 21:9): SeeDream 4.5 only\nSquare (1:1): Any model (SeeDream, Nano Banana, or Midjourney)"
      },
      {
        "title": "Q2: How do I generate 4K images with Nano Banana Pro?",
        "body": "A: ✅ Use the size parameter with the correct attribute_id.\n\nNano Banana Pro supports 3 size options via different credit_rules:\n\n1K (1024×1024): 10 pts, attribute_id 2399 (default)\n2K (2048×2048): 10 pts, attribute_id 2400\n4K (4096×4096): 18 pts, attribute_id 2401\n\nScript usage:\n\npython3 ima_image_create.py \\\n  --task-type text_to_image \\\n  --model-id gemini-3-pro-image \\\n  --prompt \"your prompt\" \\\n  --extra-params '{\"size\": \"4K\"}'\n\nThe script automatically selects the correct attribute_id (2401) when you specify size: \"4K\"."
      },
      {
        "title": "Q3: Can I generate 8K images?",
        "body": "A: ❌ No. No model currently supports 8K resolution. The maximum available is:\n\nNano Banana Pro: 4K (4096×4096)\nSeeDream 4.5 / 4.0 / 3.0: 4K (adaptive)\nAll others: ≤ 1280×1280\n\nWorkaround: Generate at maximum resolution (4K), then use external AI upscaling tools (e.g., Real-ESRGAN, Topaz Gigapixel) to upscale to 8K."
      },
      {
        "title": "Q4: Which models support custom aspect ratios?",
        "body": "A: 🌟 Multiple models now support aspect ratios!\n\n✅ NATIVE support (no virtual params needed):\n\nNano Banana Pro: 1:1, 16:9, 9:16, 4:3, 3:4 🆕\nNano Banana2: 1:1, 16:9, 9:16, 4:3, 3:4 🆕\nNano Banana MAX: 1:1, 16:9, 9:16, 4:3, 3:4 🆕\n\n✅ Virtual parameter mapping (SeeDream):\n\nSeeDream 4.5: 1:1, 16:9, 9:16, 4:3, 3:4, 2:3, 3:2, 21:9, 2k, 4k\n\n❌ NOT supported:\n\nMidjourney: Fixed 1024×1024 (1:1) only\n\nSeeDream 4.5 aspect_ratio support (8 ratios):\n\n1:1 → 2048×2048 (square, 5 pts)\n16:9 → 2560×1440 (widescreen, 5 pts)\n9:16 → 1440×2560 (vertical/portrait, 5 pts)\n4:3 → 2304×1728 (classic, 5 pts)\n3:4 → 1728×2304 (vertical, 5 pts)\n2:3 → 1664×2496 (portrait, 5 pts)\n3:2 → 2496×1664 (landscape, 5 pts)\n21:9 → 3024×1296 (ultra-wide, 5 pts)\n2k / 4k → Adaptive resolution (5 pts)\n\nNano Banana series native support (5 ratios):\n\n1:1, 16:9, 9:16, 4:3, 3:4\nNo virtual params needed, passed directly to API\n\nUsage:\n\n# SeeDream 4.5 (virtual params)\npython3 ima_image_create.py \\\n  --task-type text_to_image \\\n  --model-id doubao-seedream-4.5 \\\n  --prompt \"beautiful landscape\" \\\n  --extra-params '{\"aspect_ratio\": \"16:9\"}'\n\n# Nano Banana Pro (native support)\npython3 ima_image_create.py \\\n  --task-type text_to_image \\\n  --model-id gemini-3-pro-image \\\n  --prompt \"beautiful landscape\" \\\n  --extra-params '{\"aspect_ratio\": \"16:9\"}'\n\nHow it works (virtual param mapping for SeeDream):\n\nUser provides aspect_ratio: \"16:9\" as input\nScript queries product list and finds is_ui_virtual=true field\nApplies value_mapping: aspect_ratio: \"16:9\" → size: \"2560x1440\"\nAPI receives actual parameter: size: \"2560x1440\"\n\nNano Banana series: Aspect ratio passed directly, no mapping needed."
      },
      {
        "title": "Q5: Why does my aspect_ratio parameter get ignored?",
        "body": "A: Two possibilities:\n\nModel doesn't support it: Only SeeDream 4.5 and Nano Banana series support custom aspect ratios. Midjourney only supports 1:1 (square).\n\n\nVirtual param not available in production: For SeeDream 4.5, the is_ui_virtual=true feature may not be deployed yet. If you get 1:1 square output despite requesting 16:9, the API doesn't have the virtual parameter mapping active.\n\nSolution:\n\nUse SeeDream 4.5 or Nano Banana Pro/2/MAX for aspect ratio needs\nUse video models with custom aspect ratio, extract first frame\nPost-process: Crop or extend the image manually"
      },
      {
        "title": "Q6: What's the difference between size and resolution?",
        "body": "A:\n\nsize: For Nano Banana Pro only. Options: \"1K\", \"2K\", \"4K\". Controls output resolution via different attribute_ids.\nresolution: Used in video models (e.g., \"1080P\", \"720P\", \"4K\"). Not applicable to text_to_image models."
      },
      {
        "title": "Q7: Can I control the aspect ratio after generation?",
        "body": "A: Not directly in this skill. Options:\n\nCrop: Take the center/top/bottom portion of the square image to get desired ratio.\nExtend (inpainting): Use image editing APIs to extend the image to fill the target aspect ratio.\nVideo workaround: Use video models with desired aspect ratio, extract first frame."
      },
      {
        "title": "Common Mistakes",
        "body": "MistakeFixUsing attribute_id not from credit_rulesAlways fetch product list firstPlacing prompt at param top-levelprompt must be inside parameters[].parametersMissing app / platform in parametersRequired — use ima / webWrong credit valueMust exactly match credit_rules[].points (error 6006)size: \"adaptive\" for SeeDream 4.5 i2iUse values from form_config options onlyMissing image in both src_img_url and input_imagesBoth fields required for image_to_image"
      },
      {
        "title": "Python Example",
        "body": "import time\nimport requests\n\nBASE_URL = \"https://api.imastudio.com\"\nAPI_KEY  = \"ima_your_key_here\"\nHEADERS  = {\n    \"Authorization\":  f\"Bearer {API_KEY}\",\n    \"Content-Type\":   \"application/json\",\n    \"x-app-source\":   \"ima_skills\",\n    \"x_app_language\": \"en\",\n}\n\n\ndef get_products(category: str) -> list:\n    \"\"\"Returns flat list of type=3 version nodes from V2 tree.\"\"\"\n    r = requests.get(\n        f\"{BASE_URL}/open/v1/product/list\",\n        headers=HEADERS,\n        params={\"app\": \"ima\", \"platform\": \"web\", \"category\": category},\n    )\n    r.raise_for_status()\n    nodes = r.json()[\"data\"]\n    versions = []\n    for node in nodes:\n        for child in node.get(\"children\") or []:\n            if child.get(\"type\") == \"3\":\n                versions.append(child)\n            for gc in child.get(\"children\") or []:\n                if gc.get(\"type\") == \"3\":\n                    versions.append(gc)\n    return versions\n\n\ndef create_image_task(task_type: str, prompt: str, product: dict, input_images: list = None, **extra) -> str:\n    \"\"\"Returns task_id. task_type: 'text_to_image' or 'image_to_image'.\"\"\"\n    input_images = input_images or []\n    rule = product[\"credit_rules\"][0]\n    form_defaults = {f[\"field\"]: f[\"value\"] for f in product.get(\"form_config\", []) if f.get(\"value\") is not None}\n\n    nested_params = {\n        \"prompt\": prompt,\n        \"n\":      1,\n        \"input_images\": input_images,\n        \"cast\":   {\"points\": rule[\"points\"], \"attribute_id\": rule[\"attribute_id\"]},\n        **form_defaults,\n    }\n    nested_params.update({k: v for k, v in extra.items() if k in (\"size\",)})\n\n    body = {\n        \"task_type\":          task_type,\n        \"enable_multi_model\": False,\n        \"src_img_url\":        input_images,\n        \"parameters\": [{\n            \"attribute_id\":  rule[\"attribute_id\"],\n            \"model_id\":      product[\"model_id\"],\n            \"model_name\":    product[\"name\"],\n            \"model_version\": product[\"id\"],\n            \"app\":           \"ima\",\n            \"platform\":      \"web\",\n            \"category\":      task_type,\n            \"credit\":        rule[\"points\"],\n            \"parameters\":    nested_params,\n        }],\n    }\n    r = requests.post(f\"{BASE_URL}/open/v1/tasks/create\", headers=HEADERS, json=body)\n    r.raise_for_status()\n    return r.json()[\"data\"][\"id\"]\n\n\ndef poll(task_id: str, interval: int = 3, timeout: int = 300) -> dict:\n    deadline = time.time() + timeout\n    while time.time() < deadline:\n        r = requests.post(f\"{BASE_URL}/open/v1/tasks/detail\", headers=HEADERS, json={\"task_id\": task_id})\n        r.raise_for_status()\n        task   = r.json()[\"data\"]\n        medias = task.get(\"medias\", [])\n        if medias:\n            if any(m.get(\"status\") == \"failed\" for m in medias):\n                raise RuntimeError(f\"Task failed: {task_id}\")\n            rs = lambda m: m.get(\"resource_status\") if m.get(\"resource_status\") is not None else 0\n            if any(rs(m) == 2 for m in medias):\n                raise RuntimeError(f\"Task failed: {task_id}\")\n            if all(rs(m) == 1 for m in medias):\n                return task\n        time.sleep(interval)\n    raise TimeoutError(f\"Task timed out: {task_id}\")\n\n\n# text_to_image (SeeDream 4.5)\nproducts = get_products(\"text_to_image\")\ntask_id  = create_image_task(\"text_to_image\", \"mountain sunset, photorealistic\", products[0])\nresult   = poll(task_id)\nprint(result[\"medias\"][0][\"url\"])\n\n# text_to_image with Midjourney (artistic style)\nproducts    = get_products(\"text_to_image\")\nmidjourney  = next(p for p in products if p[\"model_id\"] == \"midjourney\")\ntask_id     = create_image_task(\"text_to_image\", \"fantasy castle, impressionist painting style\", midjourney)\nresult      = poll(task_id, interval=8)  # Midjourney: poll every 8s\nprint(result[\"medias\"][0][\"url\"])\n\n# text_to_image with aspect ratio (Nano Banana Pro - native support)\nproducts = get_products(\"text_to_image\")\nnano_pro = next(p for p in products if p[\"model_id\"] == \"gemini-3-pro-image\")\ntask_id  = create_image_task(\"text_to_image\", \"beautiful landscape\", nano_pro, aspect_ratio=\"16:9\")\nresult   = poll(task_id)\nprint(result[\"medias\"][0][\"url\"])\n\n# image_to_image (size must match form_config options, NOT \"adaptive\")\nproducts     = get_products(\"image_to_image\")\nseedream_i2i = next(p for p in products if p[\"model_id\"] == \"doubao-seedream-4.5\")\ntask_id      = create_image_task(\n    \"image_to_image\", \"turn into oil painting style\", seedream_i2i,\n    input_images=[\"https://example.com/input.jpg\",\"https://example.com/input.jpg\"],\n    size=\"4k\",\n)\nresult = poll(task_id)\nprint(result[\"medias\"][0][\"url\"])\n\n# image_to_image with Midjourney (artistic style transfer)\nproducts     = get_products(\"image_to_image\")\nmidjourney   = next(p for p in products if p[\"model_id\"] == \"midjourney\")\ntask_id      = create_image_task(\n    \"image_to_image\", \"anime style, vibrant colors\", midjourney,\n    input_images=[\"https://example.com/portrait.jpg\"],\n)\nresult = poll(task_id, interval=8)  # Midjourney: poll every 8s\nprint(result[\"medias\"][0][\"url\"])"
      },
      {
        "title": "Supported Models & Search Terms",
        "body": "Models: SeeDream 4.5, see dream, Midjourney, MJ, Nano Banana 2, Nano Banana Pro\n\nCapabilities: image generation, text-to-image, image-to-image, AI art, product photos, character design, logo design, poster, social media graphics, t2i, i2i"
      }
    ],
    "body": "IMA Image AI Creation\n⚠️ 重要：模型 ID 参考\n\nCRITICAL: When calling the script, you MUST use the exact model_id (second column), NOT the friendly model name. Do NOT infer model_id from the friendly name.\n\nQuick Reference Table:\n\n友好名称 (Friendly Name)\tmodel_id\t说明 (Notes)\nNano Banana2\tgemini-3.1-flash-image\t❌ NOT nano-banana-2, 预算选择 4-13 pts\nNano Banana Pro\tgemini-3-pro-image\t❌ NOT nano-banana-pro, 高质量 10-18 pts\nSeeDream 4.5\tdoubao-seedream-4.5\t✅ Recommended default, 5 pts\nMidjourney\tmidjourney\t✅ Same as friendly name, 8-10 pts\n\nUser Input Variations Handled by Agent:\n\n\"香蕉\" / \"香蕉2\" / \"小香蕉\" → Nano Banana2 → gemini-3.1-flash-image\n\"香蕉Pro\" / \"香蕉专业版\" / \"大香蕉\" → Nano Banana Pro → gemini-3-pro-image\n\"可梦\" / \"豆包可梦\" / \"SeeDream\" → doubao-seedream-4.5\n\"MJ\" / \"Midjourney\" → midjourney\n\nHow to get the correct model_id:\n\nCheck this table first\nUse --list-models --task-type text_to_image (or image_to_image)\nRefer to command examples below\n\nExample:\n\n# ❌ WRONG: Inferring from friendly name\n--model-id nano-banana-pro\n\n# ✅ CORRECT: Using exact model_id from table\n--model-id gemini-3-pro-image\n\n⚠️ MANDATORY PRE-CHECK: Read Knowledge Base First!\n\nIf ima-knowledge-ai is not installed: Skip all \"Read …\" steps below; use only this SKILL's default models and the 📥 User Input Parsing tables for task_type, model_id, and parameters.\n\nBEFORE executing ANY image generation task, you MUST:\n\nCheck for visual consistency needs — Read ima-knowledge-ai/references/visual-consistency.md if:\n\nUser mentions: \"系列\"、\"多张\"、\"同一个\"、\"角色\"、\"续\"、\"series\"、\"same\"\nTask involves: multiple images, character actions, product shots, video stills\nSecond+ request about same subject (e.g., \"旺财在游泳\" after \"生成旺财照片\")\n\nCheck workflow/model/parameters — Read relevant ima-knowledge-ai/references/ sections if:\n\nComplex multi-step task\nUnsure which model to use\nNeed parameter guidance (resolution, aspect ratio, etc.)\n\nWhy this matters:\n\nAI generation defaults to 独立生成 (independent generation) each time\nWithout reference images, \"same character/product\" will look different\nText-to-image CANNOT maintain visual consistency — must use image-to-image with reference\n\nExample failure case:\n\nUser: \"生成一只小狗，叫旺财\" \n  → You: generate dog image A\n\nUser: \"生成旺财在游泳的视频\"\n  → ❌ Wrong: generate new dog (looks different)\n  → ✅ Right: read visual-consistency.md → use image A as reference\n\n\nHow to check:\n\n# Step 1: Read knowledge base\nread(\"~/.openclaw/skills/ima-knowledge-ai/references/visual-consistency.md\")\n\n# Step 2: Identify if reference image needed\nif \"same subject\" or \"series\" or \"character\":\n    # Use image-to-image with previous result as reference\n    reference_image = previous_generation_result\n    use_image_to_image(prompt, reference_image, reference_strength=0.8)\nelse:\n    # OK to use text-to-image\n    use_text_to_image(prompt)\n\n\nNo exceptions — if you skip this check and generate visually inconsistent results, that's a bug.\n\n📥 User Input Parsing (Model & Parameter Recognition)\n\nPurpose: So that any agent (Claude or other models) parses user intent consistently, follow these rules when deriving task_type, model_id, and parameters from natural language. Normalize first, then map.\n\n1. User phrasing → task_type\nUser intent / phrasing\ttask_type\tNotes\nOnly text, no input image\ttext_to_image\t\"画一张…\" / \"生成图片\" / \"text to image\"\nOne input image + edit/transform\timage_to_image\t\"把这张图…\" / \"参考这张图生成\" / \"图生图\" / \"风格迁移\"\n\nIf the user attaches or links one image and asks to change it or generate something \"like this\" (same subject/style), use image_to_image with that image as input.\n\n2. Model name / alias → model_id (normalize then lookup)\n\nNormalize user wording (case-insensitive), then map to model_id:\n\nUser says (examples)\tmodel_id\tNotes\n可梦 / SeeDream / 豆包可梦 / Seedream\tdoubao-seedream-4.5\tDefault, 5 pts\nMidjourney / MJ / Mid journey\tmidjourney\tArtistic, 8–10 pts\nNano Banana / 香蕉 / Banana2 / NB2\tgemini-3.1-flash-image\tNano Banana2, 4–13 pts\nNano Banana Pro / Banana Pro / NB Pro\tgemini-3-pro-image\tPremium, 10–18 pts\n最便宜 / 最省钱 / cheapest / budget\tgemini-3.1-flash-image (512px)\t4 pts\n最好 / 最高质量 / best / premium\tgemini-3-pro-image (4K) or SeeDream 4.5\t—\n艺术 / 插画 / artistic / 画风\tmidjourney\tWhen user wants illustration/art style\n\nIf the user names a model not in the table, match by Name in the \"Supported Models\" section below and use its model_id.\n\n3. User phrasing → size / aspect_ratio\nUser says (examples)\tParameter\tNormalized value\tNotes\n16:9 / 横图 / 横向\taspect_ratio\t16:9\tSeeDream / Nano Banana 支持\n9:16 / 竖图 / 竖向\taspect_ratio\t9:16\t—\n4:3 / 3:4\taspect_ratio\t4:3 or 3:4\t—\n1:1 / 方形\taspect_ratio\t1:1\t—\n4K / 4k\tsize\t4K\tNano Banana Pro/2; Midjourney 仅 1:1\n2K / 1K / 512\tsize\t2K / 1K / 512px\tVia attribute_id for Nano Banana\n\nMidjourney: Does not support custom aspect_ratio (fixed 1024×1024). If user asks for 16:9 etc. with \"MJ\", recommend SeeDream 4.5 or Nano Banana and use their model_id. 8K: No model supports 8K; max is 4K — inform user and use 4K if they insist on \"highest resolution\".\n\n💬 User Experience Protocol (IM / Feishu / Discord) v1.3 🆕\n\nCRITICAL FIX in v1.2: Added Step 0 to ensure correct message ordering in group chats. NEW in v1.3: Added original image URL in Step 3 caption for easy copying/sharing.\n\nv1.1 Bug: Confirmation message (\"好的!来帮你画...\") appeared LAST because it used NO_REPLY. v1.2 Fix: Always reply with confirmation FIRST (Step 0), then push updates via message tool. v1.3 Enhancement: Include 🔗 原始链接：[url] in success caption so users can copy/share the URL.\n\nThis skill runs inside IM platforms (Feishu, Discord via OpenClaw).\nNever let users wait in silence. Always follow all 6 steps below, every single time.\n\n🚫 Never Say to Users\n❌ Never say\t✅ What users care about\nima_image_create.py / 脚本 / script\t—\n自动化脚本 / automation\t—\n自动处理产品列表 / 查询接口\t—\n自动解析参数 / 智能轮询\t—\nattribute_id / model_version / form_config\t—\nAPI 调用 / HTTP 请求 / 任何技术参数名\t—\n\nOnly tell users: model name · estimated time · credits · result (image/media) · plain-language status.\n\nEstimated Generation Time per Model\nModel\tEstimated Time\tPoll Every\tSend Progress Every\nSeeDream 4.5 🌟\t30~60s\t5s\t20s\nNano Banana2 💚\t20~40s\t5s\t15s\nNano Banana Pro\t60~120s\t5s\t30s\nMidjourney 🎨\t40~90s\t8s\t25s\n\nestimated_max_seconds = the upper bound of the range above (e.g. 60 for SeeDream 4.5, 120 for Nano Banana Pro, 90 for Midjourney).\n\nStep 0 — Initial Acknowledgment Reply (Normal Reply) 🆕\n\n⚠️ CRITICAL: This step is NEW in v1.2 and fixes the message ordering bug.\n\nBefore doing anything else, reply to the user with a friendly acknowledgment message using your normal reply (not message tool). This reply will automatically appear FIRST in the conversation.\n\nExample acknowledgment messages:\n\n好的!来帮你画一只萌萌的猫咪 🐱\n\n收到！马上为你生成一张 16:9 的风景照 🏔️\n\nOK! Starting image generation with SeeDream 4.5 🎨\n\n\nRules:\n\nKeep it short and warm (< 15 words)\nMatch the user's language (Chinese/English)\nInclude relevant emoji (🐱/🎨/✨)\nThis is your ONLY normal reply — all subsequent updates use message tool\n\nWhy this matters:\n\nNormal replies automatically appear FIRST in the conversation thread\nmessage tool pushes appear in chronological order AFTER your initial reply\nThis ensures users see: \"好的!\" → \"🎨 开始生成...\" → \"✅ 成功!\" (correct order)\nStep 1 — Pre-Generation Notification (Push via message tool)\n\nAfter Step 0 reply, use the message tool to push a notification immediately to the group/channel:\n\n# Agent implementation\nmessage(\n    action=\"send\",\n    target=group_id,  # or channel_id for Discord\n    message=\"\"\"🎨 开始生成图片，请稍候…\n• 模型：[Model Name]\n• 预计耗时：[X ~ Y 秒]\n• 消耗积分：[N pts]\"\"\"\n)\n\n\nUser-facing message template:\n\n🎨 开始生成图片，请稍候…\n• 模型：[Model Name]\n• 预计耗时：[X ~ Y 秒]\n• 消耗积分：[N pts]\n\n\nCost transparency examples:\n\nBalanced/default (5-6 pts): \"使用 SeeDream 4.5（5 积分，性价比最佳）\"\nPremium (>10 pts): \"使用 Nano Banana Pro（10-18 积分，最高质量，支持 1K/2K/4K）\"\nBudget (user explicit): \"使用 Nano Banana2（4 积分，最便宜最快）\"\n\nAdapt language to match the user. Chinese → 🎨 开始生成图片，请稍候… / English → 🎨 Starting image generation, please wait…\n\nStep 2 — Progress Updates (Push via message tool)\n\nImplementation:\n\nStart the generation script in background or use polling loop\nTrack elapsed time since start\nEvery [Send Progress Every] seconds (from table above), push a progress update via message tool\nStop when task completes (success/failure)\n\nProgress message template:\n\n⏳ 正在生成中… [P]%\n已等待 [elapsed]s，预计最长 [max]s\n\n\nProgress formula:\n\nP = min(95, floor(elapsed_seconds / estimated_max_seconds * 100))\n\n\nRules:\n\nCap at 95% — never show 100% until the API returns success\nIf elapsed > estimated_max: keep P at 95% and append 「稍等，即将完成…」\nExample: elapsed=40s, max=60s → P = min(95, floor(40/60*100)) = min(95, 66) = 66%\n\nWhen to send progress:\n\nShort tasks (<20s): No progress needed, skip Step 2\nMedium tasks (20-60s): Send 1-2 updates\nLong tasks (>60s): Send updates every 20-30s\nStep 3 — Success Notification (Push image via message tool)\n\nWhen task status = success, use the message tool to send the generated image directly (not as a text URL):\n\nAgent implementation:\n\n# Get result URL from script output or task detail API\nresult = get_task_result(task_id)\nimage_url = result[\"medias\"][0][\"url\"]\n\n# Build caption\ncaption = f\"\"\"✅ 图片生成成功！\n• 模型：[Model Name]\n• 耗时：预计 [X~Y]s，实际 [actual]s\n• 消耗积分：[N pts]\n\n🔗 原始链接：{image_url}\"\"\"\n\n# Add mismatch hint if user pref conflicts with knowledge-ai recommendation\nif user_pref_exists and knowledge_recommended_model != used_model:\n    caption += f\"\"\"\n\n💡 提示：当前任务也许用 {knowledge_recommended_model} 也会不错（{reason}，{cost} pts）\"\"\"\n\n# Push image + caption to group/channel\nmessage(\n    action=\"send\",\n    target=group_id,\n    media=image_url,  # Feishu/Discord will render the image\n    caption=caption\n)\n\n\nMismatch hint example:\n\n✅ 图片生成成功！\n• 模型：Midjourney（你的偏好模型）\n• 耗时：45s\n• 消耗积分：8 pts\n\n🔗 原始链接：https://...\n\n💡 提示：当前任务也许用 SeeDream 4.5 也会不错（写实风格更合适，5 pts）\n\n[图片直接显示在上方]\n\n\nImportant:\n\nHint is non-intrusive — does NOT interrupt generation\nOnly shown when user pref conflicts with knowledge-ai recommendation\nUser can ignore the hint; image is already delivered\n\nPlatform-specific notes:\n\nFeishu: message(action=send, media=url, caption=\"...\") — caption appears below image\nDiscord: Image embeds automatically from URL; caption can be in message text\nTelegram: Use message(action=send, media=url, caption=\"...\")\n\n⚠️ Important: Do NOT send plain text URL like https://cdn.../image.jpg. Users expect to see the actual image rendered.\n\nStep 4 — Failure Notification (Push via message tool)\n\nWhen task status = failed or any API/network error, push a failure message with alternative suggestions:\n\nAgent implementation:\n\nmessage(\n    action=\"send\",\n    target=group_id,\n    message=\"\"\"❌ 图片生成失败\n• 原因：[natural_language_error_message]\n• 建议改用：\n  - [Alt Model 1]（[特点]，[N pts]）\n  - [Alt Model 2]（[特点]，[N pts]）\n\n需要我帮你用其他模型重试吗？\"\"\"\n)\n\n\n⚠️ CRITICAL: Error Message Translation\n\nNEVER show technical error messages to users. Always translate API errors into natural language.\nAPI key & credits: 密钥与积分管理入口为 imaclaw.ai（与 imastudio.com 同属 IMA 平台）。Key and subscription management: imaclaw.ai (same IMA platform as imastudio.com).\n\nTechnical Error\t❌ Never Say\t✅ Say Instead (Chinese)\t✅ Say Instead (English)\n401 Unauthorized 🆕\tInvalid API key / 401 Unauthorized\t❌ API密钥无效或未授权<br>💡 生成新密钥: https://www.imaclaw.ai/imaclaw/apikey\t❌ API key is invalid or unauthorized<br>💡 Generate API Key: https://www.imaclaw.ai/imaclaw/apikey\n4008 Insufficient points 🆕\tInsufficient points / Error 4008\t❌ 积分不足，无法创建任务<br>💡 购买积分: https://www.imaclaw.ai/imaclaw/subscription\t❌ Insufficient points to create this task<br>💡 Buy Credits: https://www.imaclaw.ai/imaclaw/subscription\n\"Invalid product attribute\" / \"Insufficient points\"\tInvalid product attribute\t生成参数配置异常，请稍后重试\tConfiguration error, please try again later\nError 6006 (credit mismatch)\tError 6006\t积分计算异常，系统正在修复\tPoints calculation error, system is fixing\nError 6010 (attribute_id mismatch)\tAttribute ID does not match\t模型参数不匹配，请尝试其他模型\tModel parameters incompatible, try another model\nerror 400 (bad request, e.g. invalid size)\terror 400 / Bad request\t图片参数设置有误，请调整尺寸或比例\tImage parameter error, adjust size or aspect ratio\nresource_status == 2\tResource status 2 / Failed\t图片生成遇到问题，建议换个模型试试\tImage generation failed, try another model\nstatus == \"failed\" (no details)\tTask failed\t这次生成没成功，要不换个模型试试？\tGeneration unsuccessful, try a different model?\ntimeout\tTask timed out / Timeout error\t生成时间过长已超时，建议用更快的模型\tGeneration took too long, try a faster model\nNetwork error / Connection refused\tConnection refused / Network error\t网络连接不稳定，请检查网络后重试\tNetwork connection unstable, check network and retry\nRate limit exceeded\t429 Too Many Requests / Rate limit\t请求过于频繁，请稍等片刻再试\tToo many requests, please wait a moment\nModel unavailable\tModel not available / 503 Service Unavailable\t当前模型暂时不可用，建议换个模型\tModel temporarily unavailable, try another model\nUnsupported aspect ratio (Nano Banana Pro)\tParameter not supported\t该模型不支持自定义比例，推荐使用 SeeDream 4.5\tThis model doesn't support custom aspect ratios, try SeeDream 4.5\n\nGeneric fallback (when error is unknown):\n\nChinese: 图片生成遇到问题，请稍后重试或换个模型试试\nEnglish: Image generation encountered an issue, please try again or use another model\n\nBest Practices:\n\nFocus on user action: Tell users what to do next, not what went wrong technically\nBe reassuring: Use phrases like \"建议换个模型试试\" instead of \"生成失败了\"\nAvoid blame: Never say \"你的参数有问题\" → say \"参数需要调整一下\"\nProvide alternatives: Always suggest 1-2 alternative models in the failure message\nImage-specific: For aspect ratio errors, recommend SeeDream 4.5 (supports custom ratios)\n🆕 Include actionable links (v1.0.8+): For 401/4008 errors, provide clickable links to API key generation or credit purchase pages\n\n🆕 Enhanced Error Handling (v1.0.8):\n\nThe Reflection mechanism (3 automatic retries) now provides specific, actionable suggestions for common errors:\n\n401 Unauthorized: System suggests generating a new API key with clickable link\n4008 Insufficient Points: System suggests purchasing credits with clickable link\n500 Internal Server Error: Automatic parameter degradation (size: 4K → 2K → 1K → 512px)\n6009 No Rule Match: Automatic parameter completion from credit_rules\n6010 Attribute Mismatch: Automatic credit_rule reselection\nTimeout: Helpful info with dashboard link for background task status\n\nAll error handling is automatic and transparent — users receive natural language explanations with next steps.\n\nFailure fallback table:\n\nFailed Model\tFirst Alt\tSecond Alt\nSeeDream 4.5\tNano Banana2（4pts，快速便宜）\tNano Banana Pro（10-18pts，高质量）\nNano Banana2\tSeeDream 4.5（5pts，更高质量）\tNano Banana Pro（10-18pts）\nNano Banana Pro\tSeeDream 4.5（5pts，性价比高）\tNano Banana2（4pts，最便宜）\nAny / Unknown\tSeeDream 4.5（5pts，默认首选）\tNano Banana2（4pts，预算紧张）\nStep 5 — Done (No Further Action Needed) 🆕\n\nv1.2 Change: Step 5 is now simplified.\n\nAfter completing Steps 0-4:\n\n✅ Step 0 already sent your normal reply (appears FIRST in chat)\n✅ Steps 1-4 pushed all updates via message tool (appear in order)\n✅ No further action needed — conversation is complete\n\nDo NOT:\n\n❌ Reply again with NO_REPLY (you already replied in Step 0)\n❌ Send duplicate confirmation messages\n❌ Use message tool to send the same content twice\n\nWhy this works:\n\nUser: \"帮我画一只猫\"\n  ↓\n[Step 0] Your normal reply:  \"好的!来帮你画一只萌萌的猫咪 🐱\"  ← Appears FIRST\n  ↓\n[Step 1] message tool push:  \"🎨 开始生成图片...\"  ← Appears SECOND\n  ↓\n[Step 2] message tool push:  \"⏳ 正在生成中… 45%\"  ← (if task takes >20s)\n  ↓\n[Step 3] message tool push:  \"✅ 图片生成成功! [图片]\"  ← Appears LAST\n  ↓\n[Step 5] Done. No further replies.\n\n🎯 Summary: What Changed in v1.2 & v1.3\nVersion\tStep\tChange\nv1.2\tStep 0\t✅ NEW: Normal reply with acknowledgment (appears FIRST)\nv1.2\tStep 1\tUse message tool for notification only (not all messages)\nv1.2\tStep 5\t✅ FIXED: No further action (already replied in Step 0), no NO_REPLY\nv1.3\tStep 3\t✅ NEW: Added 🔗 原始链接：[url] in caption for easy copying\n\nRoot cause of v1.1 bug:\n\nv1.1 used message tool for ALL messages (including acknowledgment)\nThen replied NO_REPLY to suppress normal reply\nResult: Acknowledgment appeared LAST (because message tool pushes are chronological)\n\nv1.2 fix:\n\nStep 0 uses normal reply (automatically appears FIRST)\nSteps 1-4 use message tool (appear in chronological order)\nNo NO_REPLY needed (already replied in Step 0)\n\nv1.3 enhancement:\n\nStep 3 caption now includes original image URL\nUsers can easily copy/share the link without asking\nComplete Example: Correct v1.2 Flow\n# User: \"帮我画一只可爱的猫咪\"\n\n# Step 0: Normal reply (appears FIRST in chat)\n# Agent's normal response mechanism automatically handles this\nreply_text = \"好的!来帮你画一只萌萌的猫咪 🐱\"\n# (This is your normal LLM response, not a tool call)\n\n# Step 1: Push start notification\nmessage(\n    action=\"send\",\n    target=\"oc_b30b266d43b69674e3ad160de9d13cf2\",\n    message=\"🎨 开始生成图片，请稍候…\\n• 模型：SeeDream 4.5\\n• 预计耗时：30~60秒\\n• 消耗积分：5 pts\"\n)\n\n# Background: Start generation\nexec(command=\"python3 ima_image_create.py ...\", background=True, sessionId=sid)\n\n# Step 2: Progress updates (if task takes >20s)\n# (Poll in background and push updates via message tool)\nstart_time = time.time()\nwhile not done:\n    elapsed = int(time.time() - start_time)\n    if elapsed >= 20 and elapsed % 20 == 0:  # Every 20s\n        progress = min(95, int(elapsed / 60 * 100))\n        message(\n            action=\"send\",\n            target=\"oc_b30b266d43b69674e3ad160de9d13cf2\",\n            message=f\"⏳ 正在生成中… {progress}%\\n已等待 {elapsed}s，预计最长 60s\"\n        )\n    time.sleep(5)  # Poll every 5s\n\n# Step 3: Success (push image)\nresult = get_result(task_id)\nmessage(\n    action=\"send\",\n    target=\"oc_b30b266d43b69674e3ad160de9d13cf2\",\n    media=\"https://ws.esxscloud.com/.../image.jpeg\",\n    caption=f\"✅ 图片生成成功！\\n• 模型：SeeDream 4.5\\n• 耗时：实际 35s\\n• 消耗积分：5 pts\\n\\n🔗 原始链接：{result['url']}\"\n)\n\n# Step 5: Done — no further action\n# (Do NOT reply again, do NOT use NO_REPLY)\n\n\nResult in chat (correct order):\n\n[User] 帮我画一只可爱的猫咪\n\n[Agent] 好的!来帮你画一只萌萌的猫咪 🐱  ← Step 0 (normal reply)\n\n[Agent] 🎨 开始生成图片，请稍候…         ← Step 1 (message tool)\n        • 模型：SeeDream 4.5\n        • 预计耗时：30~60秒\n        • 消耗积分：5 pts\n\n[Agent] ⏳ 正在生成中… 66%                ← Step 2 (message tool, if >20s)\n        已等待 40s，预计最长 60s\n\n[Agent] ✅ 图片生成成功！                 ← Step 3 (message tool)\n        • 模型：SeeDream 4.5\n        • 耗时：实际 35s\n        • 消耗积分：5 pts\n        \n        🔗 原始链接：https://...\n        [图片]\n\n⚙️ How This Skill Works\n\nFor transparency: This skill uses a bundled Python script (scripts/ima_image_create.py) to call the IMA Open API. The script:\n\nSends your prompt to IMA's servers (two domains, see below)\nUses --user-id only locally as a key for storing your model preferences\nReturns an image URL when generation is complete\n🌐 Network Endpoints Used\n\nThis skill connects to two domains owned by IMA Studio for complete functionality:\n\nDomain\tPurpose\tWhat's Sent\tAuthentication\napi.imastudio.com\tMain API (task creation, status polling)\tPrompts, model params, task IDs\tBearer token (IMA API key)\nimapi.liveme.com\tImage upload service (OSS token generation)\tImage files (for i2i tasks), IMA API key\tIMA API key + APP_KEY signature\n\nWhy two domains?\n\napi.imastudio.com: IMA's image generation API (handles task orchestration)\nimapi.liveme.com: IMA's media storage infrastructure (handles large file uploads)\nBoth services are owned and operated by IMA Studio\n\nPrivacy implications:\n\nYour IMA API key is sent to both domains for authentication\nImage files are uploaded to imapi.liveme.com to obtain CDN URLs (for image_to_image tasks)\nImage generation happens on api.imastudio.com using the CDN URLs\nFor text_to_image tasks (no image input), only api.imastudio.com is contacted\n\nSecurity verification:\n\n# List all network endpoints in the code:\ngrep -n \"https://\" scripts/ima_image_create.py\n\n# Expected output:\n# 60: DEFAULT_BASE_URL = \"https://api.imastudio.com\"\n# 61: DEFAULT_IM_BASE_URL = \"https://imapi.liveme.com\"\n\n\nIf you're concerned about the two-domain architecture:\n\nReview IMA Studio's privacy policy at https://imastudio.com/privacy\nContact IMA technical support to confirm domain ownership: support@imastudio.com\nUse a test/scoped API key first (see security notice below)\n⚠️ Credential Security Notice\n\nYour IMA API key is sent to TWO domains:\n\napi.imastudio.com — Main image generation API\nimapi.liveme.com — Image upload service (only when using image_to_image tasks)\n\nBoth domains are owned by IMA Studio, but if you're concerned about credential exposure:\n\n✅ Best practices:\n\nUse a test/scoped API key for initial testing (create at https://imastudio.com/api-keys)\nSet a low quota (e.g., 100 credits) for the test key\nRotate your key after testing if needed\nContact IMA support to confirm domain ownership: support@imastudio.com\n\n❌ Do NOT:\n\nUse a production key if you're uncomfortable with the two-domain architecture\nShare your API key with others\nCommit your API key to version control\n\nWhat gets sent to IMA servers:\n\n✅ Your image prompt/description\n✅ Model selection (SeeDream/Nano Banana/Midjourney)\n✅ Image parameters (size, quality, aspect ratio, etc.)\n✅ Image files (for image_to_image tasks, uploaded to imapi.liveme.com)\n✅ IMA API key (for authentication to both domains)\n❌ NO user_id (it's only used locally)\n\nWhat's stored locally:\n\n~/.openclaw/memory/ima_prefs.json - Your model preferences (< 1 KB)\n~/.openclaw/logs/ima_skills/ - Generation logs (auto-deleted after 7 days)\nAgent Execution (Internal Reference)\n\nNote for users: You can review the script source at scripts/ima_image_create.py anytime.\nThe agent uses this script to simplify API calls. Network requests go to two IMA Studio domains: api.imastudio.com (API) and imapi.liveme.com (image uploads for i2i tasks).\n\nUse the bundled script internally to ensure correct parameter construction:\n\n# List available models\npython3 {baseDir}/scripts/ima_image_create.py \\\n  --api-key  $IMA_API_KEY \\\n  --task-type text_to_image \\\n  --list-models\n\n# Generate image\npython3 {baseDir}/scripts/ima_image_create.py \\\n  --api-key  $IMA_API_KEY \\\n  --task-type text_to_image \\\n  --model-id  doubao-seedream-4.5 \\\n  --prompt   \"a cute puppy running on grass\" \\\n  --user-id  {user_id} \\\n  --output-json\n\n# Image to image\npython3 {baseDir}/scripts/ima_image_create.py \\\n  --api-key      $IMA_API_KEY \\\n  --task-type    image_to_image \\\n  --model-id     doubao-seedream-4.5 \\\n  --prompt       \"turn into oil painting style\" \\\n  --input-images https://example.com/photo.jpg \\\n  --user-id      {user_id} \\\n  --output-json\n\n\n✅ Local images: --input-images accepts both HTTPS URLs and local file paths. Local files are automatically uploaded to IMA CDN by the script (no need to host them first).\n\nThe script outputs JSON — parse it to get the result URL and pass it to the user via the UX protocol messages above.\n\nOverview\n\nCall IMA Open API to create AI-generated images. All endpoints require an ima_* API key. The core flow is: query products → create task → poll until done.\n\n🔒 Security & Transparency Policy\n\nThis skill is community-maintained and open for inspection.\n\n✅ What Users CAN Do\n\nFull transparency:\n\n✅ Review all source code: Check scripts/ima_image_create.py and ima_logger.py anytime\n✅ Verify network calls: Network requests go to two IMA Studio domains: api.imastudio.com (API) and imapi.liveme.com (image uploads for i2i tasks). See \"🌐 Network Endpoints Used\" section above for full details.\n✅ Inspect local data: View ~/.openclaw/memory/ima_prefs.json and log files\n✅ Control privacy: Delete preferences/logs anytime, or disable file writes (see below)\n\nConfiguration allowed:\n\n✅ Set API key in environment or agent config:\nEnvironment variable: export IMA_API_KEY=ima_your_key_here\nOpenClaw/MCP config: Add IMA_API_KEY to agent's environment configuration\nGet your key at: https://imastudio.com\n✅ Use scoped/test keys: Test with limited API keys, rotate after testing\n✅ Disable file writes: Make prefs/logs read-only or symlink to /dev/null\n\nData control:\n\n✅ View stored data: cat ~/.openclaw/memory/ima_prefs.json\n✅ Delete preferences: rm ~/.openclaw/memory/ima_prefs.json (resets to defaults)\n✅ Delete logs: rm -rf ~/.openclaw/logs/ima_skills/ (auto-cleanup after 7 days anyway)\n⚠️ Advanced Users: Fork & Modify\n\nIf you need to modify this skill for your use case:\n\nFork the repository (don't modify the original)\nUpdate your fork with your changes\nTest thoroughly with limited API keys\nDocument your changes for troubleshooting\n\nNote: Modified skills may break API compatibility or introduce security issues. Official support only covers the unmodified version.\n\n❌ What to AVOID (Security Risks)\n\nActions that could compromise security:\n\n❌ Sharing API keys publicly or in skill files\n❌ Modifying API endpoints to unknown servers\n❌ Disabling SSL/TLS certificate verification\n❌ Logging sensitive user data (prompts, IDs, etc.)\n❌ Bypassing authentication or billing mechanisms\n\nWhy this matters:\n\nAPI Compatibility: Skill logic aligns with IMA Open API schema\nSecurity: Malicious modifications could leak credentials or bypass billing\nSupport: Modified skills may not be supported\nCommunity: Breaking changes affect all users\n📋 Privacy & Data Handling Summary\n\nWhat this skill does with your data:\n\nData Type\tSent to IMA?\tStored Locally?\tUser Control\nImage prompts\t✅ Yes (required for generation)\t❌ No\tNone (required)\nAPI key\t✅ Yes (authentication header)\t❌ No\tSet via env var\nuser_id (optional CLI arg)\t❌ Never (local preference key only)\t✅ Yes (as prefs file key)\tChange --user-id value\nModel preferences\t❌ No\t✅ Yes (~/.openclaw)\tDelete anytime\nGeneration logs\t❌ No\t✅ Yes (~/.openclaw)\tAuto-cleanup 7 days\n\nPrivacy recommendations:\n\nUse test/scoped API keys for initial testing\nNote: --user-id is never sent to IMA servers - it's only used locally as a key for storing preferences in ~/.openclaw/memory/ima_prefs.json\nReview source code at scripts/ima_image_create.py to verify network calls (search for create_task function)\nRotate API keys after testing or if compromised\n\nGet your IMA API key: Visit https://imastudio.com to register and get started.\n\n🔧 For Skill Maintainers Only\n\nVersion control:\n\nAll changes must go through Git with proper version bumps (semver)\nCHANGELOG.md must document all changes\nProduction deployments require code review\n\nFile checksums (optional):\n\n# Verify skill integrity\nsha256sum SKILL.md scripts/ima_image_create.py\n\n\nIf users report issues, verify file integrity first.\n\n🧠 User Preference Memory\n\nUser preferences have highest priority when they exist. But preferences are only saved when users explicitly express model preferences — not from automatic model selection.\n\nStorage: ~/.openclaw/memory/ima_prefs.json\n{\n  \"user_{user_id}\": {\n    \"text_to_image\": {\n      \"model_id\":   \"doubao-seedream-4.5\",\n      \"model_name\": \"SeeDream 4.5\",\n      \"credit\":     5,\n      \"last_used\":  \"2026-02-26T03:07:27Z\"\n    },\n    \"image_to_image\": {\n      \"model_id\":   \"doubao-seedream-4.5\",\n      \"model_name\": \"SeeDream 4.5\",\n      \"credit\":     5,\n      \"last_used\":  \"2026-02-25T10:00:00Z\"\n    }\n  }\n}\n\nModel Selection Flow (Every Generation)\n\nStep 1: Get knowledge-ai recommendation (if installed)\n\nknowledge_recommended_model = read_ima_knowledge_ai()  # e.g., \"SeeDream 4.5\"\n\n\nStep 2: Check user preference\n\nuser_pref = load_prefs().get(f\"user_{user_id}\", {}).get(task_type)  # e.g., {\"model_id\": \"midjourney\", ...}\n\n\nStep 3: Decide which model to use\n\nif user_pref exists:\n    use_model = user_pref[\"model_id\"]  # Highest priority\nelse:\n    use_model = knowledge_recommended_model or fallback_default\n\n\nStep 4: Check for mismatch (for later hint)\n\nif user_pref exists and knowledge_recommended_model != user_pref[\"model_id\"]:\n    mismatch = True  # Will add hint in success message\n\nWhen to Write (User Explicit Preference ONLY)\n\n✅ Save preference when user explicitly specifies a model:\n\nUser says\tAction\n用XXX / 换成XXX / 改用XXX\tSwitch to model XXX + save as preference\n以后都用XXX / 默认用XXX / always use XXX\tSave + confirm: ✅ 已记住！以后图片生成默认用 [XXX]\n我喜欢XXX / 我更喜欢XXX\tSave as preference\n\n❌ Do NOT save when:\n\nAgent auto-selects from knowledge-ai → not user preference\nAgent uses fallback default → not user preference\nUser says generic quality requests (see \"Clear Preference\" below) → clear preference instead\nWhen to Clear (User Abandons Preference)\n\n🗑️ Clear preference when user wants automatic selection:\n\nUser says\tAction\n用最好的 / 用最合适的 / best / recommended\tClear pref + use knowledge-ai recommendation\n推荐一个 / 你选一个 / 自动选择\tClear pref + use knowledge-ai recommendation\n用默认的 / 用新的\tClear pref + use knowledge-ai recommendation\n试试别的 / 换个试试 (without specific model)\tClear pref + use knowledge-ai recommendation\n重新推荐\tClear pref + use knowledge-ai recommendation\n\nImplementation:\n\ndel prefs[f\"user_{user_id}\"][task_type]\nsave_prefs(prefs)\n\n⭐ Model Selection Priority\n\nSelection flow:\n\nUser preference (if exists) → Highest priority, always respect\nima-knowledge-ai skill (if installed) → Professional recommendation based on task\nFallback defaults → Use table below (only if neither 1 nor 2 exists)\n\nImportant notes:\n\nUser preference is only saved when user explicitly specifies a model (see \"When to Write\" above)\nKnowledge-ai is always consulted (even when user pref exists) to detect mismatches\nWhen mismatch detected → add gentle hint in success message (does NOT interrupt generation)\n\nThe defaults below are FALLBACK only. User preferences have highest priority, then knowledge-ai recommendations.\nAlways default to the newest and most popular model. Do NOT default to the cheapest.\n\nTask\tDefault Model\tmodel_id\tversion_id\tCost\tWhy\ntext_to_image\tSeeDream 4.5\tdoubao-seedream-4.5\tdoubao-seedream-4-5-251128\t5 pts\tLatest doubao flagship, photorealistic 4K\ntext_to_image (budget)\tNano Banana2\tgemini-3.1-flash-image\tgemini-3.1-flash-image\t4 pts\tFastest and cheapest option\ntext_to_image (premium)\tNano Banana Pro\tgemini-3-pro-image\tgemini-3-pro-image-preview\t10/10/18 pts\tPremium quality, 1K/2K/4K options\ntext_to_image (artistic)\tMidjourney 🎨\tmidjourney\tv6\t8/10 pts\tArtist-level aesthetics, creative styles\nimage_to_image\tSeeDream 4.5\tdoubao-seedream-4.5\tdoubao-seedream-4-5-251128\t5 pts\tLatest, best i2i quality\nimage_to_image (budget)\tNano Banana2\tgemini-3.1-flash-image\tgemini-3.1-flash-image\t4 pts\tCheapest option\nimage_to_image (premium)\tNano Banana Pro\tgemini-3-pro-image\tgemini-3-pro-image-preview\t10 pts\tPremium quality\nimage_to_image (artistic)\tMidjourney 🎨\tmidjourney\tv6\t8/10 pts\tArtist-level aesthetics, style transfer\n\nSelection guide by use case:\n\nGeneral image generation → SeeDream 4.5 (5pts)\nCustom aspect ratio (16:9, 9:16, 4:3, etc.) → SeeDream 4.5 🌟 or Nano Banana Pro/2/MAX 🆕 (native support)\nBudget-conscious / fast generation → Nano Banana2 (4pts)\nHighest quality with size control (1K/2K/4K) → Nano Banana Pro (text_to_image: 10-18pts, image_to_image: 10pts)\nArtistic/creative styles, illustrations, paintings → Midjourney 🎨 (8-10pts)\nStyle transfer / image editing → SeeDream 4.5 (5pts) or Midjourney 🎨 (artistic)\n\n🆕 MAJOR UPDATE: Nano Banana series now has NATIVE aspect_ratio support!\n\nNano Banana Pro: ✅ Supports aspect_ratio (1:1, 16:9, 9:16, 4:3, 3:4) NATIVELY\nNano Banana2: ✅ Supports aspect_ratio (1:1, 16:9, 9:16, 4:3, 3:4) NATIVELY\nNano Banana MAX: ✅ Supports aspect_ratio (1:1, 16:9, 9:16, 4:3, 3:4) NATIVELY\n\nWhen user requests unsupported combinations:\n\nMidjourney + aspect_ratio (16:9, etc.): Recommend SeeDream 4.5 or Nano Banana series instead\n\n❌ Midjourney 暂不支持自定义 aspect_ratio（仅支持 1024x1024 方形）\n\n✅ 推荐方案：\n  1. SeeDream 4.5（支持虚拟参数 aspect_ratio）\n  2. Nano Banana Pro/2/MAX（原生支持 aspect_ratio）\n     • 支持比例：1:1, 16:9, 9:16, 4:3, 3:4\n\n\n• 成本：5 积分（性价比最佳） • 质量：4K photorealistic\n\n需要我帮你用 SeeDream 4.5 生成吗？\n\nAny model + 8K: Inform user no model supports 8K, max is 4K (Nano Banana Pro or SeeDream 4.5)\n\nAny model + 7:3 ratio: Non-standard ratio, not supported. Suggest closest supported ratio (e.g., 21:9 for ultra-wide, 2:3 for portrait)\n\nSupported Models\n\n⚠️ Production Environment: 4 image models are currently available in production (as of 2026-02-28).\n\ntext_to_image (4 models)\nName\tmodel_id\tversion_id\tCost\tattribute_id\tSize Options\nSeeDream 4.5 🌟\tdoubao-seedream-4.5\tdoubao-seedream-4-5-251128\t5 pts\t2341\tDefault (adaptive 4k)\nNano Banana2 💚\tgemini-3.1-flash-image\tgemini-3.1-flash-image-preview\t4/6/10/13 pts\t4400/4401/4402/4403\t512px (4pts) / 1K (6pts) / 2K (10pts) / 4K (13pts)\nNano Banana Pro\tgemini-3-pro-image\tgemini-3-pro-image-preview\t10/10/18 pts\t2399/2400/2401\t1K (10pts) / 2K (10pts) / 4K (18pts)\nMidjourney 🎨\tmidjourney\tv6\t8/10 pts\t5451/5452\t480p (8pts) / 720p (10pts)\nimage_to_image (4 models)\nName\tmodel_id\tversion_id\tCost\tattribute_id\tSize Options\nSeeDream 4.5 🌟\tdoubao-seedream-4.5\tdoubao-seedream-4-5-251128\t5 pts\t1611\tDefault (adaptive 4k)\nNano Banana2 💚\tgemini-3.1-flash-image\tgemini-3.1-flash-image-preview\t4/6/10/13 pts\t4404/4405/4406/4407\t512px (4pts) / 1K (6pts) / 2K (10pts) / 4K (13pts)\nNano Banana Pro\tgemini-3-pro-image\tgemini-3-pro-image-preview\t10 pts\t2402/2403/2404\t1K (10pts) / 2K (10pts) / 4K (18pts)\nMidjourney 🎨\tmidjourney\tv6\t8/10 pts\t5453/5454\t480p (8pts) / 720p (10pts)\nRecommended Defaults (Based on Production Data)\nTask Type\tDefault Model\tReason\tCost\ntext_to_image\tSeeDream 4.5\tLatest DouBao flagship, balanced quality/cost\t5 pts\ntext_to_image (budget)\tNano Banana2\tFastest and cheapest option\t4 pts\ntext_to_image (artistic)\tMidjourney 🎨\tArtist-level aesthetics, creative styles\t8-10 pts\nimage_to_image\tSeeDream 4.5\tNewest, most stable, cost-effective\t5 pts (attribute_id: 1611)\nimage_to_image (budget)\tNano Banana2\tCheapest option\t4 pts\nimage_to_image (artistic)\tMidjourney 🎨\tArtist-level aesthetics, style transfer\t8-10 pts\n\nPremium option: Nano Banana Pro — Highest quality with size control (1K/2K/4K), higher cost (10-18 pts for text_to_image, 10 pts for image_to_image).\n\nModel Capabilities (Parameter Support)\n\n⚠️ Critical: Models have varying parameter support. Custom aspect ratios are now supported by multiple models.\n\nModel\tCustom Aspect Ratio\tMax Resolution\tSize Options\tNotes\nSeeDream 4.5\t✅ (via virtual params)\t4K (adaptive)\t8 aspect ratios\tSupports 1:1, 16:9, 9:16, 4:3, 3:4, 2:3, 3:2, 21:9 (5 pts)\nNano Banana2\t✅ Native support 🆕\t4K (4096×4096)\t512px/1K/2K/4K + aspect ratios\tSupports 1:1, 16:9, 9:16, 4:3, 3:4; size via attribute_id\nNano Banana Pro\t✅ Native support 🆕\t4K (4096×4096)\t1K/2K/4K + aspect ratios\tSupports 1:1, 16:9, 9:16, 4:3, 3:4; size via attribute_id\nMidjourney 🎨\t❌ (1:1 only)\t1024px (square)\t480p/720p via attribute_id\tFixed 1024x1024, artistic style focus\n\nKey Capabilities:\n\n✅ Aspect ratio control: SeeDream 4.5 (virtual params), Nano Banana Pro/2/MAX (native support)\n❌ 8K: Not supported by any model (max is 4K)\n✅ Size control: Nano Banana2, Nano Banana Pro, and Midjourney support multiple size options via different attribute_ids\n✅ Budget option: Nano Banana2 is the cheapest at 4 pts for 512px, but 4K costs 13pts\n🎨 Artistic styles: Midjourney excels at creative, artistic, and illustration styles\n💡 Best value: SeeDream 4.5 at 5pts offers aspect ratio flexibility; Nano Banana2 512px at 4pts for fastest/cheapest\nEnvironment\n\nBase URL: https://api.imastudio.com\n\nRequired/recommended headers for all /open/v1/ endpoints:\n\nHeader\tRequired\tValue\tNotes\nAuthorization\t✅\tBearer ima_your_api_key_here\tAPI key authentication\nx-app-source\t✅\tima_skills\tFixed value — identifies skill-originated requests\nx_app_language\trecommended\ten / zh\tProduct label language; defaults to en if omitted\nAuthorization: Bearer ima_your_api_key_here\nx-app-source: ima_skills\nx_app_language: en\n\n⚠️ MANDATORY: Always Query Product List First\n\nCRITICAL: You MUST call /open/v1/product/list BEFORE creating any task.\nThe attribute_id field is REQUIRED in the create request. If it is 0 or missing, you get:\n\"Invalid product attribute\" → \"Insufficient points\" → task fails completely.\nNEVER construct a create request from the model table alone. Always fetch the product first.\n\nWhy attribute_id is required\n\nThe attribute_id uniquely identifies the exact product variant (model + quality tier). The billing and routing system uses it to:\n\nValidate the product is purchasable\nDeduct the correct credits via credit_rules\nRoute the request to the right backend model\nHow to get attribute_id\n# Step 1: Query product list for the target category\nGET /open/v1/product/list?app=ima&platform=web&category=text_to_image\n\n# Step 2: Walk the V2 tree to find your model (type=3 leaf nodes only)\nfor group in response[\"data\"]:\n    for version in group.get(\"children\", []):\n        if version[\"type\"] == \"3\" and version[\"model_id\"] == target_model_id:\n            attribute_id = version[\"credit_rules\"][0][\"attribute_id\"]\n            credit       = version[\"credit_rules\"][0][\"points\"]\n            model_version = version[\"id\"]    # = version_id\n            model_name    = version[\"name\"]\n            form_defaults = {f[\"field\"]: f[\"value\"] for f in version[\"form_config\"]}\n\nQuick Reference: Known attribute_ids\n\n⚠️ Production warning: attribute_id and credit values change frequently. Always call /open/v1/product/list at runtime; table below is pre-queried reference (2026-02-27).\n\ntext_to_image:\n\nModel\tmodel_id\tattribute_id\tcredit\tSize\nSeeDream 4.5 🌟\tdoubao-seedream-4.5\t2341\t5 pts\tDefault (adaptive 4k)\nNano Banana2 (512px)\tgemini-3.1-flash-image\t4400\t4 pts\t512px (512×512)\nNano Banana2 (1K)\tgemini-3.1-flash-image\t4401\t6 pts\t1K (1024×1024)\nNano Banana2 (2K)\tgemini-3.1-flash-image\t4402\t10 pts\t2K (2048×2048)\nNano Banana2 (4K)\tgemini-3.1-flash-image\t4403\t13 pts\t4K (4096×4096)\nNano Banana Pro (1K)\tgemini-3-pro-image\t2399\t10 pts\t1K (1024×1024)\nNano Banana Pro (2K)\tgemini-3-pro-image\t2400\t10 pts\t2K (2048×2048)\nNano Banana Pro (4K)\tgemini-3-pro-image\t2401\t18 pts\t4K (4096×4096)\n\nimage_to_image:\n\nModel\tmodel_id\tattribute_id\tcredit\tSize\nSeeDream 4.5 🌟\tdoubao-seedream-4.5\t1611\t5 pts\tDefault (adaptive 4k)\nNano Banana2 (512px)\tgemini-3.1-flash-image\t4404\t4 pts\t512px (512×512)\nNano Banana2 (1K)\tgemini-3.1-flash-image\t4405\t6 pts\t1K (1024×1024)\nNano Banana2 (2K)\tgemini-3.1-flash-image\t4406\t10 pts\t2K (2048×2048)\nNano Banana2 (4K)\tgemini-3.1-flash-image\t4407\t13 pts\t4K (4096×4096)\nNano Banana Pro (1K)\tgemini-3-pro-image\t2402\t10 pts\t1K (1024×1024)\nNano Banana Pro (2K)\tgemini-3-pro-image\t2403\t10 pts\t2K (2048×2048)\nNano Banana Pro (4K)\tgemini-3-pro-image\t2404\t10 pts\t4K (4096×4096)\n\n⚠️ Note: Production has 3 models (SeeDream 4.5 + Nano Banana2 + Nano Banana Pro). All other models mentioned in older documentation are no longer available.\n\nCore Flow\n1. GET /open/v1/product/list?app=ima&platform=web&category=<type>\n   → REQUIRED: Get attribute_id, credit, model_version, form_config defaults\n\n[image_to_image only]\n2. Upload input image → get public HTTPS URL\n   → See \"Image Upload\" section below\n\n3. POST /open/v1/tasks/create\n   → Must include: attribute_id, model_name, model_version, credit, cast, prompt (nested!)\n\n4. POST /open/v1/tasks/detail  {task_id: \"...\"}\n   → Poll every 2–5s until medias[].resource_status == 1\n   → Extract url from completed media\n\nCommon Mistakes (and resulting errors)\nMistake\tError\nattribute_id is 0 or missing\t\"Invalid product attribute\" → Insufficient points\nattribute_id outdated (production changed)\tSame errors; always query product list first\nprompt at outer level instead of parameters.parameters.prompt\tPrompt ignored or error\ncast missing from inner parameters\tBilling validation failure\ncredit wrong / missing\tError 6006\nmodel_name or model_version missing\tWrong model routing\nSkip product list, use hardcoded values\tAll of the above\nImage Upload (Required for image_to_image)\n\nThe IMA Open API does NOT accept raw bytes or base64 images. All input images must be public HTTPS URLs.\n\nScript behavior: --input-images accepts both URLs and local file paths. When you pass a local path, the script automatically uploads the file to IMA CDN (imapi.liveme.com) and uses the returned URL — no separate upload step needed when calling the script.\n\nWhen a user provides an image (local file, bytes, base64) and you invoke the script with a path or URL, the script handles upload for local paths. If you have bytes/base64, upload first using the IMA presigned URL flow below (or write to a temp file and pass that path).\n\nTwo-Step Upload Flow\nStep 1: GET /api/rest/oss/getuploadtoken  → { ful, fdl }\nStep 2: PUT {ful}  with raw image bytes\n         → use fdl (CDN URL) as input_images value\n\n\nSee ima-all-ai/SKILL.md → \"Image Upload\" section for the complete implementation.\n\nQuick Reference\n# If user provides a URL already → use directly\nif source.startswith(\"https://\"):\n    input_url = source\n\n# If user provides a local file → upload first\nelse:\n    token = get_upload_token(uid, ima_token, suffix=\"jpeg\",\n                             content_type=\"image/jpeg\", ...)\n    upload_image_to_oss(image_bytes, \"image/jpeg\", token[\"ful\"])\n    input_url = token[\"fdl\"]   # CDN URL → use as input_images\n\n# Then create task\ntask_id = create_task(\"image_to_image\", prompt, product,\n                      input_images=[input_url], size=\"4k\")\n\n\nCDN: https://ima-ga.esxscloud.com/ | OSS: zhubite-imagent-bot.oss-us-east-1.aliyuncs.com\n\nSupported Task Types\ncategory\tCapability\tInput\ntext_to_image\tText → Image\tprompt\nimage_to_image\tImage → Image\tprompt + input image URL\nDetail API status values\nField\tType\tValues\nresource_status\tint or null\t0=处理中, 1=可用, 2=失败, 3=已删除；null 当作 0\nstatus\tstring\t\"pending\", \"processing\", \"success\", \"failed\"\nresource_status\tstatus\tAction\n0 or null\tpending / processing\tKeep polling\n1\tsuccess (or completed)\tStop when all medias are 1; read url\n1\tfailed\tStop, handle error\n2 / 3\tany\tStop, handle error\n\nImportant: Treat resource_status: null as 0. Stop only when all medias have resource_status == 1. Check status != \"failed\" when rs=1.\n\nAPI 1: Product List\nGET /open/v1/product/list?app=ima&platform=web&category=text_to_image\n\n\nReturns a V2 tree structure: type=2 nodes are model groups, type=3 nodes are versions (leaves). Only type=3 nodes contain credit_rules and form_config.\n\n[\n  {\n    \"id\": \"SeeDream\",\n    \"type\": \"2\",\n    \"name\": \"SeeDream\",\n    \"model_id\": \"\",\n    \"children\": [\n      {\n        \"id\": \"doubao-seedream-4-5-251128\",\n        \"type\": \"3\",\n        \"name\": \"SeeDream 4.5\",\n        \"model_id\": \"doubao-seedream-4.5\",\n        \"credit_rules\": [\n          { \"attribute_id\": 2341, \"points\": 5, \"attributes\": { \"default\": \"enabled\" } }\n        ],\n        \"form_config\": [\n          { \"field\": \"size\", \"type\": \"tags\", \"value\": \"4k\",\n            \"options\": [{\"label\":\"2K\",\"value\":\"2k\"}, {\"label\":\"4K\",\"value\":\"4k\"}] }\n        ]\n      }\n    ]\n  }\n]\n\n\nHow to pick a version for task creation:\n\nTraverse nodes to find type=3 leaves (versions)\nUse model_id and id (= model_version) from the leaf\nPick credit_rules[].attribute_id matching your desired quality/size\nUse form_config[].value as default parameters values\nAPI 2: Create Task\nPOST /open/v1/tasks/create\n\ntext_to_image — Verified ✅\n\nNo image input. src_img_url: [], input_images: [].\n\n{\n  \"task_type\": \"text_to_image\",\n  \"enable_multi_model\": false,\n  \"src_img_url\": [],\n  \"parameters\": [{\n    \"attribute_id\":  2341,\n    \"model_id\":      \"doubao-seedream-4.5\",\n    \"model_name\":    \"SeeDream 4.5\",\n    \"model_version\": \"doubao-seedream-4-5-251128\",\n    \"app\":           \"ima\",\n    \"platform\":      \"web\",\n    \"category\":      \"text_to_image\",\n    \"credit\":        5,\n    \"parameters\": {\n      \"prompt\":       \"a beautiful mountain sunset, photorealistic\",\n      \"size\":         \"4k\",\n      \"n\":            1,\n      \"input_images\": [],\n      \"cast\":         {\"points\": 5, \"attribute_id\": 2341}\n    }\n  }]\n}\n\nimage_to_image — Verified ✅\n{\n  \"task_type\": \"image_to_image\",\n  \"enable_multi_model\": false,\n  \"src_img_url\": [\"https://example.com/input.jpg\"],\n  \"parameters\": [{\n    \"attribute_id\":  1611,\n    \"model_id\":      \"doubao-seedream-4.5\",\n    \"model_name\":    \"SeeDream 4.5\",\n    \"model_version\": \"doubao-seedream-4-5-251128\",\n    \"app\":           \"ima\",\n    \"platform\":      \"web\",\n    \"category\":      \"image_to_image\",\n    \"credit\":        5,\n    \"parameters\": {\n      \"prompt\":       \"turn into oil painting style\",\n      \"size\":         \"4k\",\n      \"n\":            1,\n      \"input_images\": [\"https://example.com/input.jpg\",\"https://example.com/input.jpg\"],\n      \"cast\":         {\"points\": 5, \"attribute_id\": 1611}\n    }\n  }]\n}\n\n\n⚠️ size must be from form_config options (e.g. \"2k\", \"4k\", \"2048x2048\"). \"adaptive\" is NOT valid for SeeDream 4.5 — causes error 400. Top-level src_img_url and parameters.input_images must both contain the input image URL.\n\nKey fields:\n\nField\tRequired\tDescription\nparameters[].credit\t✅\tMust equal credit_rules[].points. Error 6006 if wrong.\nparameters[].parameters.prompt\t✅\tPrompt must be nested here, NOT at top level.\nparameters[].parameters.cast\t✅\t{\"points\": N, \"attribute_id\": N} — mirror of credit.\nparameters[].parameters.n\t✅\tNumber of outputs (usually 1).\nparameters[].parameters.input_images\timage_to_image\tArray of input image URLs.\ntop-level src_img_url\timage_to_image\tMust also contain the input image URL.\n\nResponse: data.id = task ID for polling.\n\nAPI 3: Task Detail (Poll)\nPOST /open/v1/tasks/detail\n{\"task_id\": \"<id from create response>\"}\n\n\nPoll every 2–5s. Completed response:\n\n{\n  \"id\": \"task_abc\",\n  \"medias\": [{\n    \"resource_status\": 1,\n    \"url\": \"https://cdn.../output.jpg\",\n    \"format\": \"jpg\",\n    \"width\": 1024,\n    \"height\": 1024\n  }]\n}\n\n\nOutput fields: url, width, height, format (jpg/png).\n\nFAQ: Parameter Support & Limitations\nQ1: Can I generate 16:9 or 7:3 aspect ratio images?\n\nA: ✅ YES! Multiple models now support custom aspect ratios.\n\n✅ Supported aspect ratios:\n\nSeeDream 4.5: 1:1, 16:9, 9:16, 4:3, 3:4, 2:3, 3:2, 21:9 (via virtual params)\nNano Banana Pro/2/MAX: 1:1, 16:9, 9:16, 4:3, 3:4 (native support) 🆕\n\n❌ Not supported:\n\nMidjourney: Fixed 1024×1024 (1:1 only)\nCustom ratios: 7:3, 8:3, or other non-standard ratios are NOT supported by any model\n\nWorkarounds for unsupported ratios:\n\nUse video models (recommended): Generate with video models (e.g., Wan 2.6 text_to_video) that support 16:9, 9:16, 1:1, then extract the first frame as an image.\nPost-processing: Generate a 1:1 image, then crop/extend to desired aspect ratio.\n\nModel recommendation by aspect ratio need:\n\nStandard ratios (16:9, 9:16, 4:3, 3:4): Nano Banana Pro/2 (native support, no virtual params)\nExtended ratios (2:3, 3:2, 21:9): SeeDream 4.5 only\nSquare (1:1): Any model (SeeDream, Nano Banana, or Midjourney)\nQ2: How do I generate 4K images with Nano Banana Pro?\n\nA: ✅ Use the size parameter with the correct attribute_id.\n\nNano Banana Pro supports 3 size options via different credit_rules:\n\n1K (1024×1024): 10 pts, attribute_id 2399 (default)\n2K (2048×2048): 10 pts, attribute_id 2400\n4K (4096×4096): 18 pts, attribute_id 2401\n\nScript usage:\n\npython3 ima_image_create.py \\\n  --task-type text_to_image \\\n  --model-id gemini-3-pro-image \\\n  --prompt \"your prompt\" \\\n  --extra-params '{\"size\": \"4K\"}'\n\n\nThe script automatically selects the correct attribute_id (2401) when you specify size: \"4K\".\n\nQ3: Can I generate 8K images?\n\nA: ❌ No. No model currently supports 8K resolution. The maximum available is:\n\nNano Banana Pro: 4K (4096×4096)\nSeeDream 4.5 / 4.0 / 3.0: 4K (adaptive)\nAll others: ≤ 1280×1280\n\nWorkaround: Generate at maximum resolution (4K), then use external AI upscaling tools (e.g., Real-ESRGAN, Topaz Gigapixel) to upscale to 8K.\n\nQ4: Which models support custom aspect ratios?\n\nA: 🌟 Multiple models now support aspect ratios!\n\n✅ NATIVE support (no virtual params needed):\n\nNano Banana Pro: 1:1, 16:9, 9:16, 4:3, 3:4 🆕\nNano Banana2: 1:1, 16:9, 9:16, 4:3, 3:4 🆕\nNano Banana MAX: 1:1, 16:9, 9:16, 4:3, 3:4 🆕\n\n✅ Virtual parameter mapping (SeeDream):\n\nSeeDream 4.5: 1:1, 16:9, 9:16, 4:3, 3:4, 2:3, 3:2, 21:9, 2k, 4k\n\n❌ NOT supported:\n\nMidjourney: Fixed 1024×1024 (1:1) only\n\nSeeDream 4.5 aspect_ratio support (8 ratios):\n\n1:1 → 2048×2048 (square, 5 pts)\n16:9 → 2560×1440 (widescreen, 5 pts)\n9:16 → 1440×2560 (vertical/portrait, 5 pts)\n4:3 → 2304×1728 (classic, 5 pts)\n3:4 → 1728×2304 (vertical, 5 pts)\n2:3 → 1664×2496 (portrait, 5 pts)\n3:2 → 2496×1664 (landscape, 5 pts)\n21:9 → 3024×1296 (ultra-wide, 5 pts)\n2k / 4k → Adaptive resolution (5 pts)\n\nNano Banana series native support (5 ratios):\n\n1:1, 16:9, 9:16, 4:3, 3:4\nNo virtual params needed, passed directly to API\n\nUsage:\n\n# SeeDream 4.5 (virtual params)\npython3 ima_image_create.py \\\n  --task-type text_to_image \\\n  --model-id doubao-seedream-4.5 \\\n  --prompt \"beautiful landscape\" \\\n  --extra-params '{\"aspect_ratio\": \"16:9\"}'\n\n# Nano Banana Pro (native support)\npython3 ima_image_create.py \\\n  --task-type text_to_image \\\n  --model-id gemini-3-pro-image \\\n  --prompt \"beautiful landscape\" \\\n  --extra-params '{\"aspect_ratio\": \"16:9\"}'\n\n\nHow it works (virtual param mapping for SeeDream):\n\nUser provides aspect_ratio: \"16:9\" as input\nScript queries product list and finds is_ui_virtual=true field\nApplies value_mapping: aspect_ratio: \"16:9\" → size: \"2560x1440\"\nAPI receives actual parameter: size: \"2560x1440\"\n\nNano Banana series: Aspect ratio passed directly, no mapping needed.\n\nQ5: Why does my aspect_ratio parameter get ignored?\n\nA: Two possibilities:\n\nModel doesn't support it: Only SeeDream 4.5 and Nano Banana series support custom aspect ratios. Midjourney only supports 1:1 (square).\n\nVirtual param not available in production: For SeeDream 4.5, the is_ui_virtual=true feature may not be deployed yet. If you get 1:1 square output despite requesting 16:9, the API doesn't have the virtual parameter mapping active.\n\nSolution:\n\nUse SeeDream 4.5 or Nano Banana Pro/2/MAX for aspect ratio needs\nUse video models with custom aspect ratio, extract first frame\nPost-process: Crop or extend the image manually\nQ6: What's the difference between size and resolution?\n\nA:\n\nsize: For Nano Banana Pro only. Options: \"1K\", \"2K\", \"4K\". Controls output resolution via different attribute_ids.\nresolution: Used in video models (e.g., \"1080P\", \"720P\", \"4K\"). Not applicable to text_to_image models.\nQ7: Can I control the aspect ratio after generation?\n\nA: Not directly in this skill. Options:\n\nCrop: Take the center/top/bottom portion of the square image to get desired ratio.\nExtend (inpainting): Use image editing APIs to extend the image to fill the target aspect ratio.\nVideo workaround: Use video models with desired aspect ratio, extract first frame.\nCommon Mistakes\nMistake\tFix\nUsing attribute_id not from credit_rules\tAlways fetch product list first\nPlacing prompt at param top-level\tprompt must be inside parameters[].parameters\nMissing app / platform in parameters\tRequired — use ima / web\nWrong credit value\tMust exactly match credit_rules[].points (error 6006)\nsize: \"adaptive\" for SeeDream 4.5 i2i\tUse values from form_config options only\nMissing image in both src_img_url and input_images\tBoth fields required for image_to_image\nPython Example\nimport time\nimport requests\n\nBASE_URL = \"https://api.imastudio.com\"\nAPI_KEY  = \"ima_your_key_here\"\nHEADERS  = {\n    \"Authorization\":  f\"Bearer {API_KEY}\",\n    \"Content-Type\":   \"application/json\",\n    \"x-app-source\":   \"ima_skills\",\n    \"x_app_language\": \"en\",\n}\n\n\ndef get_products(category: str) -> list:\n    \"\"\"Returns flat list of type=3 version nodes from V2 tree.\"\"\"\n    r = requests.get(\n        f\"{BASE_URL}/open/v1/product/list\",\n        headers=HEADERS,\n        params={\"app\": \"ima\", \"platform\": \"web\", \"category\": category},\n    )\n    r.raise_for_status()\n    nodes = r.json()[\"data\"]\n    versions = []\n    for node in nodes:\n        for child in node.get(\"children\") or []:\n            if child.get(\"type\") == \"3\":\n                versions.append(child)\n            for gc in child.get(\"children\") or []:\n                if gc.get(\"type\") == \"3\":\n                    versions.append(gc)\n    return versions\n\n\ndef create_image_task(task_type: str, prompt: str, product: dict, input_images: list = None, **extra) -> str:\n    \"\"\"Returns task_id. task_type: 'text_to_image' or 'image_to_image'.\"\"\"\n    input_images = input_images or []\n    rule = product[\"credit_rules\"][0]\n    form_defaults = {f[\"field\"]: f[\"value\"] for f in product.get(\"form_config\", []) if f.get(\"value\") is not None}\n\n    nested_params = {\n        \"prompt\": prompt,\n        \"n\":      1,\n        \"input_images\": input_images,\n        \"cast\":   {\"points\": rule[\"points\"], \"attribute_id\": rule[\"attribute_id\"]},\n        **form_defaults,\n    }\n    nested_params.update({k: v for k, v in extra.items() if k in (\"size\",)})\n\n    body = {\n        \"task_type\":          task_type,\n        \"enable_multi_model\": False,\n        \"src_img_url\":        input_images,\n        \"parameters\": [{\n            \"attribute_id\":  rule[\"attribute_id\"],\n            \"model_id\":      product[\"model_id\"],\n            \"model_name\":    product[\"name\"],\n            \"model_version\": product[\"id\"],\n            \"app\":           \"ima\",\n            \"platform\":      \"web\",\n            \"category\":      task_type,\n            \"credit\":        rule[\"points\"],\n            \"parameters\":    nested_params,\n        }],\n    }\n    r = requests.post(f\"{BASE_URL}/open/v1/tasks/create\", headers=HEADERS, json=body)\n    r.raise_for_status()\n    return r.json()[\"data\"][\"id\"]\n\n\ndef poll(task_id: str, interval: int = 3, timeout: int = 300) -> dict:\n    deadline = time.time() + timeout\n    while time.time() < deadline:\n        r = requests.post(f\"{BASE_URL}/open/v1/tasks/detail\", headers=HEADERS, json={\"task_id\": task_id})\n        r.raise_for_status()\n        task   = r.json()[\"data\"]\n        medias = task.get(\"medias\", [])\n        if medias:\n            if any(m.get(\"status\") == \"failed\" for m in medias):\n                raise RuntimeError(f\"Task failed: {task_id}\")\n            rs = lambda m: m.get(\"resource_status\") if m.get(\"resource_status\") is not None else 0\n            if any(rs(m) == 2 for m in medias):\n                raise RuntimeError(f\"Task failed: {task_id}\")\n            if all(rs(m) == 1 for m in medias):\n                return task\n        time.sleep(interval)\n    raise TimeoutError(f\"Task timed out: {task_id}\")\n\n\n# text_to_image (SeeDream 4.5)\nproducts = get_products(\"text_to_image\")\ntask_id  = create_image_task(\"text_to_image\", \"mountain sunset, photorealistic\", products[0])\nresult   = poll(task_id)\nprint(result[\"medias\"][0][\"url\"])\n\n# text_to_image with Midjourney (artistic style)\nproducts    = get_products(\"text_to_image\")\nmidjourney  = next(p for p in products if p[\"model_id\"] == \"midjourney\")\ntask_id     = create_image_task(\"text_to_image\", \"fantasy castle, impressionist painting style\", midjourney)\nresult      = poll(task_id, interval=8)  # Midjourney: poll every 8s\nprint(result[\"medias\"][0][\"url\"])\n\n# text_to_image with aspect ratio (Nano Banana Pro - native support)\nproducts = get_products(\"text_to_image\")\nnano_pro = next(p for p in products if p[\"model_id\"] == \"gemini-3-pro-image\")\ntask_id  = create_image_task(\"text_to_image\", \"beautiful landscape\", nano_pro, aspect_ratio=\"16:9\")\nresult   = poll(task_id)\nprint(result[\"medias\"][0][\"url\"])\n\n# image_to_image (size must match form_config options, NOT \"adaptive\")\nproducts     = get_products(\"image_to_image\")\nseedream_i2i = next(p for p in products if p[\"model_id\"] == \"doubao-seedream-4.5\")\ntask_id      = create_image_task(\n    \"image_to_image\", \"turn into oil painting style\", seedream_i2i,\n    input_images=[\"https://example.com/input.jpg\",\"https://example.com/input.jpg\"],\n    size=\"4k\",\n)\nresult = poll(task_id)\nprint(result[\"medias\"][0][\"url\"])\n\n# image_to_image with Midjourney (artistic style transfer)\nproducts     = get_products(\"image_to_image\")\nmidjourney   = next(p for p in products if p[\"model_id\"] == \"midjourney\")\ntask_id      = create_image_task(\n    \"image_to_image\", \"anime style, vibrant colors\", midjourney,\n    input_images=[\"https://example.com/portrait.jpg\"],\n)\nresult = poll(task_id, interval=8)  # Midjourney: poll every 8s\nprint(result[\"medias\"][0][\"url\"])\n\nSupported Models & Search Terms\n\nModels: SeeDream 4.5, see dream, Midjourney, MJ, Nano Banana 2, Nano Banana Pro\n\nCapabilities: image generation, text-to-image, image-to-image, AI art, product photos, character design, logo design, poster, social media graphics, t2i, i2i"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/allenfancy-gan/ima-image-ai",
    "publisherUrl": "https://clawhub.ai/allenfancy-gan/ima-image-ai",
    "owner": "allenfancy-gan",
    "version": "1.0.5",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/ima-image-ai",
    "downloadUrl": "https://openagent3.xyz/downloads/ima-image-ai",
    "agentUrl": "https://openagent3.xyz/skills/ima-image-ai/agent",
    "manifestUrl": "https://openagent3.xyz/skills/ima-image-ai/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/ima-image-ai/agent.md"
  }
}