feat (provider/bytedance): add Seedream image model support - #17121
Conversation
Add a ByteDance Seedream image model to @ai-sdk/bytedance, exposed via `.image()` / `.imageModel()`. Uses ByteDance ARK's single JSON `/images/generations` endpoint for both text-to-image and image-to-image (input images passed in the `image` field), rather than an OpenAI-style multipart `/images/edits` endpoint. - Typed provider options (`ByteDanceImageModelOptions`) mapping camelCase keys to ARK request fields, with passthrough for unknown fields. - Unit tests covering generate, edit (single/multi/URL), option mapping, and unsupported-setting warnings. - Provider docs: add Image Models section with basic + edit examples and link the ModelArk image generation API. - Example scripts under examples/ai-functions/generate-image/bytedance. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a Seedream multi-reference image edit example following the black-forest-labs edit-multi-reference example for inputs/prompt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…xample Pass comic-cat.png + comic-dog.png as file bytes instead of remote URLs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…mage docs The AI SDK abstracts the transport; remove references to the request endpoint and the b64_json response format from the image model docs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| maxImages?: number | null; | ||
|
|
||
| /** | ||
| * Prompt optimization mode. `seedream-4-0` supports both `'standard'` and | ||
| * `'fast'`; other models support `'standard'` only. | ||
| */ | ||
| optimizePromptMode?: 'standard' | 'fast' | null; |
There was a problem hiding this comment.
Design decision — flat vs. nested provider options (feedback wanted)
I flattened ByteDance's two nested request objects into single camelCase options:
maxImages→sequential_image_generation_options.max_imagesoptimizePromptMode→optimize_prompt_options.mode
The model reassembles the nested ModelArk shape before sending.
Why flat: cleaner typed surface, and today each nested object has exactly one documented field, so a nested option would just be a one-key wrapper.
Trade-off: if ByteDance adds more fields under either object later, a flat API needs a new top-level option each time, whereas mirroring ARK 1:1 (sequentialImageGenerationOptions: { maxImages }, optimizePromptOptions: { mode }) would extend naturally and read closer to the API docs.
Preference on flat vs. nested here? Happy to switch before merge.
@felixarntz for any steering, I figure we can do flattened for now and switch to sub-objects if warranted later (and be backwards compatible).
…abilities table Seedream 5.0 Lite's primary id is `seedream-5-0-260128`; ByteDance's docs list `seedream-5-0-lite-260128` as an additional id for the same model. Addresses PR review bot flag. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The API has no output-count parameter, so maxImagesPerCall = 10 made
generateImage({ n: 2 }) issue a single call that returned one image.
Set it to 1 so generateImage fans n out into n single-image calls, and
drop the now-misleading `n` unsupported warning. Batches of related
images remain available via the sequentialImageGeneration option.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
The cherry-picked PR targeted V4 provider specs, which don't exist on release-v6.0. Adapt the Seedream image model to V3: - bytedance-provider.ts / index.ts: keep ProviderV3 / Experimental_VideoModelV3 and the existing ByteDanceVideoProviderOptions export; add image support via ImageModelV3. - bytedance-image-model.ts + test: ImageModelV4 -> ImageModelV3, SharedV4Warning -> SharedV3Warning, specificationVersion 'v4' -> 'v3'. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…#17189) This is an automated backport of #17121 to the release-v6.0 branch. FYI @shaper This backport has conflicts that need to be resolved manually. ### `git cherry-pick` output ``` Auto-merging content/providers/01-ai-sdk-providers/85-bytedance.mdx Auto-merging packages/bytedance/src/bytedance-provider.ts CONFLICT (content): Merge conflict in packages/bytedance/src/bytedance-provider.ts Auto-merging packages/bytedance/src/index.ts CONFLICT (content): Merge conflict in packages/bytedance/src/index.ts error: could not apply 7fd7dab... feat (provider/bytedance): add Seedream image model support (#17121) hint: After resolving the conflicts, mark them with hint: "git add/rm <pathspec>", then run hint: "git cherry-pick --continue". hint: You can instead skip this commit with "git cherry-pick --skip". hint: To abort and get back to the state before "git cherry-pick", hint: run "git cherry-pick --abort". hint: Disable this message with "git config set advice.mergeConflict false" ``` --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Walter Korman <shaper@vercel.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Adds a ByteDance Seedream image model to
@ai-sdk/bytedance, exposed via.image()/.imageModel(). Previously the provider only supported video and threwNoSuchModelErrorfor image models.The gateway serves ByteDance images through
@ai-sdk/openai-compatible, whose image model routes edits to a multipart/images/editsendpoint. ByteDance ARK has no such endpoint — text-to-image and image-to-image both use a single JSONPOST /images/generations, with input images passed in theimagefield (string or array). Routing edits to/images/editsproduced non-JSON responses ("Invalid JSON response"). This model implements the correct ARK shape.Changes
bytedance-image-model.ts—ImageModelV4using ARK's single JSON/images/generations; input images (single or multi) go in theimagefield viaconvertImageModelFileToDataUri(URLs pass through, binary/base64 → data URI).response_formatpinned tob64_json.bytedance-image-model-options.ts— typedByteDanceImageModelOptions(looseObjectschema, mirroring the video model):watermark,outputFormat,size(resolution level),sequentialImageGeneration,maxImages,optimizePromptMode; camelCase → ARK snake_case with passthrough for unknown fields.bytedance-image-settings.ts—ByteDanceImageModelId(known Seedream ids + open string forep-…endpoints).image/imageModelinto the provider; exported new types fromindex.ts.sizeoverride, unknown-option passthrough, unsupported-setting warnings (aspectRatio,seed,n,mask).85-bytedance.mdx(text-to-image, edit, multi-image blending, options table, capabilities table) + link to the ModelArk image generation API.generate-image/bytedance/{basic,edit,edit-multi-reference}.ts.@ai-sdk/bytedanceminor.Verification
tsc --noEmit: clean (package + examples)vitest run(package): all tests passpnpm build: successUnsupported inputs warn rather than break:
aspectRatio(→ usesize),seed,n>1(→sequentialImageGeneration), andmask(Seedream has no mask-based inpainting).Linear: AIG-145 (https://linear.app/vercel/issue/AIG-145)