Skill: raezhliu/dola-seedream (version 1.0.3)

--- name: dola-seedream description: Generate high-quality images from text prompts using BytePlus Seedream models. Supports multiple artistic styles and aspect ratios. Use this skill when users want to create images from text descriptions, generate artwork in various styles, create visual content for creative projects, or need AI-powered image generation capabilities. license: MIT tags: ["image-generation", "seedream", "dola", "byteplus", "ai-art", "text-to-image", "image-to-image"] --- # dola-seedream ## Description Generate high-quality images from text prompts using BytePlus Seedream models. This skill provides access to three powerful Seedream model versions (4.0, 4.5, and 5.0), each offering unique capabilities for different use cases. ## When to Use This Skill Use this skill when: - Users want to create images from text descriptions - Users need to generate artwork in various artistic styles - Users want to create visual content for creative projects - Users need AI-powered image generation capabilities - Users want to convert reference images to different styles - Users need to generate multiple images in batch - Users require high-quality, professional-looking images ## Model Versions | Version | Model Name | Release Date | Recommendation | Best For | | -------- | ------------------- | ------------- | -------------- | -------------------------------------------------- | | 4.0 | seedream-4-0-250828 | August 2025 | ⭐⭐⭐ | Daily use, supports 1K/2K/4K and Fast mode | | 4.5 | seedream-4-5-251128 | November 2025 | ⭐⭐⭐⭐ | Detail-oriented, supports 2K/4K | | 5.0-lite | seedream-5-0-260128 | 2026 | ⭐⭐⭐⭐⭐ | Highest quality, supports 2K/3K and PNG output | ## Features - **Text-to-Image**: Generate images from detailed text descriptions - **Image-to-Image**: Transform reference images (up to 14) into new creations - **Batch Generation**: Create multiple related images in a single request (up to 15) - **Flexible Resolution**: Support for resolution presets (1K, 2K, 3K, 4K) or custom sizes - **Multiple Versions**: Choose from 4.0, 4.5, or 5.0-lite models - **Watermark Control**: Option to disable watermarks - **Output Formats**: PNG and JPEG formats (5.0-lite only) - **Prompt Optimization**: Choose between `standard` and `fast` (for 4.0) modes ## Installation & Setup ### Prerequisites ```bash # Required: API Key configuration (Get from BytePlus Console) export ARK_DOLA_API_KEY="your-api-key-here" ``` ## Usage ### Command Line ```bash python scripts/seedream_image_generate.py -p "A cute kitten playing in a garden" --version 5.0 ``` ## Command Line Options | Option | Shortcut | Description | Default | | ------------------- | -------- | ----------------------------------------------- | ------------ | | `--prompt` | `-p` | Image description text (required) | - | | `--version` | `-v` | Version selection: `4.0`, `4.5`, `5.0-lite` | `5.0-lite` | | `--size` | `-s` | Image dimensions (1K/2K/3K/4K or WxH) | `2K` | | `--image` | `-i` | Single reference image URL | - | | `--images` | - | Multiple reference image URLs (space separated) | - | | `--group` | `-g` | Enable batch image generation | `false` | | `--max-images` | - | Maximum images for batch generation | `15` | | `--output-format` | - | Output format: `png` or `jpeg` (5.0-lite only) | `jpeg` | | `--response-format` | - | Response format: `url` or `b64_json` | `url` | | `--prompt-mode` | - | Prompt optimization mode: `standard` or `fast` | `standard` | | `--timeout` | `-t` | Timeout in seconds | `1200` | | `--no-watermark` | - | Disable watermark | `false` | | `--stream` | - | Enable server-side streaming | `false` | ## Python API Usage ```python import asyncio from scripts.seedream_image_generate import seedream_generate async def main(): # Generate image using 5.0 version result = await seedream_generate([ { "prompt": "A futuristic city landscape", "size": "2048x2048", "output_format": "png" } ], version="5.0") print(result) if __name__ == "__main__": asyncio.run(main()) ``` ## Version Selection Guide ### Choose 4.0 if: - You need quick daily generation - Quality requirements are not extremely high - You need faster generation speed - Simple scenes and styles ### Choose 4.5 if: - You want richer details - You're working with complex scenes - You need better style reproduction - You have moderate quality requirements ### Choose 5.0 (Recommended) if: - You want the highest quality - You need breakthrough creative expression - You have extreme detail requirements - **You need tools parameter (like web search)** ⭐ - **You need custom output format (png/jpeg)** ⭐ - Important projects and work **When in doubt, use 5.0!** ⭐ ## Prompt Engineering Tips ### Basic Prompt Structure ``` [Subject Description] + [Style/Art Movement] + [Lighting/Atmosphere] + [Quality/Resolution] ``` ### Advanced Prompts (Optimized for 5.0) ``` [Subject Description], [Creative Style/Art Movement], [Unique Perspective/Composition], [Special Lighting/Atmosphere], [Emphasizing 5.0 creative expression] ``` ## Parameter Support by Version | Parameter | Seedream 4.0 | Seedream 4.5 | Seedream 5.0 | Description | | ----------------------------------- | ------------ | ------------ | ------------ | ---------------------------------- | | model | ✅ | ✅ | ✅ | Model name | | prompt | ✅ | ✅ | ✅ | Prompt (required) | | image | ✅ | ✅ | ✅ | Reference image(s) | | size | ✅ | ✅ | ✅ | Image dimensions | | sequential_image_generation | ✅ | ✅ | ✅ | Batch generation control | | sequential_image_generation_options | ✅ | ✅ | ✅ | Batch generation config | | response_format | ✅ | ✅ | ✅ | Response format (url/b64_json) | | watermark | ✅ | ✅ | ✅ | Watermark (true/false) | | stream | ✅ | ✅ | ✅ | Streaming output | | optimize_prompt_options | ✅ | ✅ | ✅ | Prompt optimization config | | **tools** | ❌ | ❌ | **✅** | Tool configuration (5.0 only) | | **output_format** | ❌ | ❌ | **✅** | Output format (png/jpeg, 5.0 only) | ## FAQ ### Q: What's the difference between the versions? A: 4.0 is for quick daily use, 4.5 offers better details for complex scenes, and 5.0 provides the highest quality with unique tools support. ### Q: How long are generated URLs valid? A: URLs are valid for 24 hours. Please download and save your images promptly. ### Q: What image formats are supported for references? A: Common formats like JPG and PNG are supported, provided via URL or Base64. ### Q: Can I use multiple versions in one call? A: Currently, only one version per call. For comparisons, make separate calls for different versions. ## License This skill is licensed under the Apache License 2.0. See the LICENSE file for details. ## Notice Please comply with BytePlus's terms of service and relevant laws and regulations when using this skill.

path: scripts/seedream_image_generate.py
content: #!/usr/bin/env python3
# MIT License
# Copyright (c) 2026
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
dola-seedream - Generate high-quality images from text prompts
using BytePlus Seedream models (4.0, 4.5, and 5.0).

Documentation: https://docs.byteplus.com/en/docs/ModelArk/1399008
"""

import argparse
import asyncio
import json
import os
import sys
import logging
from typing import Dict, List, Tuple, Optional

import httpx

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
logger = logging.getLogger(__name__)

# Configuration constants
[REDACTED_SECRET]"ARK_DOLA_API_KEY")
API_BASE = os.getenv(
    "ARK_DOLA_API_BASE", 
    "https://ark.ap-southeast.bytepluses.com/api/v3"
).rstrip("/")

# Model names for each version
MODELS = {
    "4.0": "seedream-4-0-250828",
    "4.5": "seedream-4-5-251128",
    "5.0-lite": "seedream-5-0-260128",
    "5.0": "seedream-5-0-260128",
}

# Supported fields per version (based on official documentation)
SUPPORTED_FIELDS = {
    "4.0": ["size", "response_format", "watermark", "image", "sequential_image_generation", "sequential_image_generation_options", "stream", "optimize_prompt_options"],
    "4.5": ["size", "response_format", "watermark", "image", "sequential_image_generation", "sequential_image_generation_options", "stream", "optimize_prompt_options"],
    "5.0-lite": ["size", "response_format", "watermark", "image", "sequential_image_generation", "sequential_image_generation_options", "stream", "optimize_prompt_options", "output_format"],
    "5.0": ["size", "response_format", "watermark", "image", "sequential_image_generation", "sequential_image_generation_options", "stream", "optimize_prompt_options", "output_format"],
}

# Version descriptions
VERSION_DESCRIPTIONS = {
    "4.0": "Seedream 4.0 - Stable for daily use, support 1K/2K/4K resolution and fast mode.",
    "4.5": "Seedream 4.5 - Improved detail, support 2K/4K resolution.",
    "5.0-lite": "Seedream 5.0-lite - Highest quality, support 2K/3K resolution and PNG output.",
    "5.0": "Seedream 5.0 (alias for 5.0-lite) - Latest features.",
}

def _get_headers() -> dict:
    if not API_KEY:
        raise ValueError("Missing ARK_DOLA_API_KEY environment variable.")
    return {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {API_KEY}",
    }

def _build_request_body(item: dict, model_name: str, version: str) -> dict:
    body = {
        "model": model_name,
        "prompt": item.get("prompt", ""),
    }

    supported_fields = SUPPORTED_FIELDS.get(version, [])
    for field in supported_fields:
        if field in item and item[field] is not None:
            body[field] = item[field]

    # Batch generation options
    if item.get("sequential_image_generation") == "auto":
        options = dict(item.get("sequential_image_generation_options") or {})
        if "max_images" in item:
            options["max_images"] = item["max_images"]
        if options:
            body["sequential_image_generation_options"] = options

    # Prompt optimization options
    if "prompt_mode" in item and item["prompt_mode"]:
        body["optimize_prompt_options"] = {"mode": item["prompt_mode"]}

    return body

async def _call_image_api(client: httpx.AsyncClient, item: dict, model_name: str, version: str) -> dict:
    url = f"{API_BASE}/images/generations"
    body = _build_request_body(item, model_name, version)
    
    response = await client.post(url, headers=_get_headers(), json=body)
    if response.status_code != 200:
        try:
            error_data = response.json()
            error_msg = error_data.get("error", {}).get("message", response.text)
        except Exception:
            error_msg = response.text
        raise RuntimeError(f"API Error ({response.status_code}): {error_msg}")
    
    return response.json()

async def handle_single_task(
    client: httpx.AsyncClient,
    idx: int,
    item: dict,
    model_name: str,
    version: str,
    semaphore: asyncio.Semaphore
) -> Tuple[List[dict], List[str], List[dict]]:
    async with semaphore:
        success_list = []
        error_list = []
        error_detail_list = []

        try:
            response = await _call_image_api(client, item, model_name, version)

            if "error" not in response:
                data_list = response.get("data", [])
                for i, image_data in enumerate(data_list):
                    image_name = f"task_{idx}_image_{i}"

                    if "error" in image_data:
                        error_list.append(image_name)
                        error_detail_list.append({"task_idx": idx, "image_name": image_name, "error": image_data.get("error")})
                        continue

                    image_url = image_data.get("url")
                    if image_url:
                        success_list.append({image_name: image_url})
                    else:
                        b64 = image_data.get("b64_json")
                        if b64:
                            output_format = item.get("output_format", "jpeg")
                            mime_type = f"image/{output_format}"
                            success_list.append({image_name: f"data:{mime_type};base64,{b64}"})
                        else:
                            error_list.append(image_name)
                            error_detail_list.append({"task_idx": idx, "image_name": image_name, "error": "missing data (no url/b64)"})
            else:
                error_info = response.get("error", {})
                error_list.append(f"task_{idx}")
                error_detail_list.append({"task_idx": idx, "error": error_info})

        except Exception as e:
            error_list.append(f"task_{idx}")
            error_detail_list.append({"task_idx": idx, "error": str(e)})

        return success_list, error_list, error_detail_list

async def seedream_generate(
    tasks: List[dict],
    version: str = "5.0",
    timeout: int = 1200,
    concurrency: int = 5
) -> Dict:
    if version not in MODELS:
        return {"status": "error", "error_list": [f"Unsupported version: {version}"]}

    if not [REDACTED_SECRET] {"status": "error", "error_list": ["Missing ARK_DOLA_API_KEY environment variable."]}

    model_name = MODELS[version]
    semaphore = asyncio.Semaphore(concurrency)
    
    async with httpx.AsyncClient(timeout=float(timeout)) as client:
        coroutines = [handle_single_task(client, idx, item, model_name, version, semaphore) for idx, item in enumerate(tasks)]
        results = await asyncio.gather(*coroutines, return_exceptions=True)

    success_list = []
    error_list = []
    error_detail_list = []

    for res in results:
        if isinstance(res, Exception):
            error_list.append("exception")
            error_detail_list.append({"error": str(res)})
        else:
            s, e, ed = res
            success_list.extend(s)
            error_list.extend(e)
            error_detail_list.extend(ed)

    return {
        "status": "success" if success_list else "error",
        "success_list": success_list,
        "error_list": error_list,
        "error_detail_list": error_detail_list,
        "model": model_name,
        "version": version,
    }

def main():
    parser = argparse.ArgumentParser(
        description="dola-seedream - Generate images using BytePlus Seedream models",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="Versions:\n" + "\n".join([f"  {k}: {v}" for k, v in VERSION_DESCRIPTIONS.items()])
    )
    parser.add_argument("--prompt", "-p", help="Image description text")
    parser.add_argument("--version", "-v", choices=list(MODELS.keys()), default="5.0-lite", help="Model version (default 5.0-lite)")
    parser.add_argument("--size", "-s", help="Image dimensions (e.g., 2048x2048 or resolution 1K/2K/3K/4K)")
    parser.add_argument("--image", "-i", help="Reference image URL")
    parser.add_argument("--images", nargs="+", help="Multiple reference image URLs")
    parser.add_argument("--group", "-g", action="store_true", help="Enable batch generation")
    parser.add_argument("--max-images", type=int, default=15, help="Max images for batch (1-15)")
    parser.add_argument("--output-format", choices=["png", "jpeg"], default="jpeg", help="Output format (5.0-lite only)")
    parser.add_argument("--response-format", choices=["url", "b64_json"], default="url", help="Response format")
    parser.add_argument("--prompt-mode", choices=["standard", "fast"], help="Prompt optimization mode (fast only for 4.0)")
    parser.add_argument("--timeout", "-t", type=int, default=1200, help="Timeout in seconds")
    parser.add_argument("--no-watermark", action="store_true", help="Disable watermark")
    parser.add_argument("--stream", action="store_true", help="Enable streaming request (non-blocking server side)")
    
    args = parser.parse_args()

    if not args.prompt:
        parser.print_help()
        sys.exit(1)

    # Set default size if not provided
    size = args.size
    if not size:
        if args.version in ["4.0", "4.5", "5.0-lite", "5.0"]:
            size = "2K"
        else:
            size = "2048x2048"

    task = {
        "prompt": args.prompt,
        "size": size,
        "response_format": args.response_format,
        "watermark": not args.no_watermark,
        "stream": args.stream
    }

    if args.version in ["5.0", "5.0-lite"]:
        task["output_format"] = args.output_format
    
    if args.prompt_mode:
        task["prompt_mode"] = args.prompt_mode
    
    if args.images:
        task["image"] = args.images
    elif args.image:
        task["image"] = args.image

    if args.group:
        task["sequential_image_generation"] = "auto"
        task["max_images"] = max(1, min(15, args.max_images))

    result = asyncio.run(seedream_generate([task], version=args.version, timeout=args.timeout))
    print(json.dumps(result, indent=2, ensure_ascii=False))

if __name__ == "__main__":
    main()


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: malicious | SkillSpector: suspicious (HIGH)