Migrates AI image generation from Google Gemini 2.5 Flash SDK to BytePlus SeeDream v4.5 REST API in TypeScript/JavaScript projects. Guides env updates, client creation, and API route migration for cost and quality optimization.
npx claudepluginhub joshuarweaver/cascade-code-general-misc-4 --plugin julianromli-ai-skillsThis skill uses the workspace's default tool permissions.
Migrate AI image generation from Google Gemini 2.5 Flash Image to BytePlus SeeDream v4.5 with this proven, production-ready workflow.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Migrate AI image generation from Google Gemini 2.5 Flash Image to BytePlus SeeDream v4.5 with this proven, production-ready workflow.
Migration Overview:
Benefits:
Prerequisites:
Time Estimate: 3-4 hours for complete migration
Replace Gemini environment variables with BytePlus configuration.
Find and remove Gemini configuration:
# REMOVE
GEMINI_API_KEY=your_google_ai_api_key_here
Add BytePlus configuration:
# ADD
BYTEPLUS_API_KEY=your_byteplus_api_key_here
If you have environment validation (recommended), update it to check for BYTEPLUS_API_KEY instead of GEMINI_API_KEY.
Example changes:
// OLD
{
name: 'GEMINI_API_KEY',
required: true,
description: 'Google AI API key for image generation',
setupUrl: 'https://aistudio.google.com/app/apikey',
}
// NEW
{
name: 'BYTEPLUS_API_KEY',
required: true,
description: 'BytePlus SeeDream API key for image generation',
setupUrl: 'https://console.byteplus.com/ark/region:ark+ap-southeast-1/apiKey',
}
Add to your .env.local:
BYTEPLUS_API_KEY=your_actual_byteplus_api_key
Test that validation detects the new key correctly:
npm run validate # or your validation command
Create a reusable REST API client for BytePlus SeeDream v4.5.
Create lib/byteplus-client.ts (or appropriate path for your project).
See references/client-template.ts for a fully commented, production-ready template.
Key implementation points:
fetch API (no SDK required)data:image/png;base64,${base64String}Choose appropriate parameters for your use case:
Model ID: seedream-4-5-251128 (latest as of Dec 2025)
Size options:
2048x2560 (portrait), 2560x2048 (landscape), 2048x2048 (square)2K, 4K (model determines exact dimensions)Prompt optimization:
mode: "standard" - Higher quality, slower (~45-60s)mode: "fast" - Good quality, faster (~15-30s)Other settings:
sequential_image_generation: "disabled" - Single image outputwatermark: false - No watermarkresponse_format: "b64_json" - Base64 responseCreate a simple test to verify the client works:
const result = await generateImageWithByteplus({
prompt: "A simple test image of a red circle",
images: [] // or test images
})
console.log(result.imageUrl ? "Success!" : result.error)
Replace Gemini SDK calls with BytePlus client in all API routes.
In each API route file:
// REMOVE
import { GoogleGenAI } from "@google/genai"
Add BytePlus import:
// ADD
import { generateImageWithByteplus } from "@/lib/byteplus-client"
Before (Gemini SDK):
const genAI = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY! })
const result = await genAI.models.generateContent({
model: "gemini-2.5-flash-image",
contents: [{
role: "user",
parts: [
{ text: prompt },
{ inlineData: { mimeType: "image/png", data: base64Image1 } },
{ inlineData: { mimeType: "image/jpeg", data: base64Image2 } }
]
}],
config: {
responseModalities: ["IMAGE"],
imageConfig: { aspectRatio: "4:5" }
}
})
// Extract image from candidates
const imagePart = result.candidates[0].content.parts.find(p => p.inlineData)
const base64Image = `data:${imagePart.inlineData.mimeType};base64,${imagePart.inlineData.data}`
After (BytePlus REST):
const result = await generateImageWithByteplus({
prompt: prompt,
images: [
{ data: base64Image1, mimeType: "image/png" },
{ data: base64Image2, mimeType: "image/jpeg" }
]
})
if (result.error) {
return NextResponse.json({ error: result.error }, { status: 500 })
}
// Image already in data URI format
const base64Image = result.imageUrl
BytePlus doesn't return text alongside images. If your frontend expects both:
return NextResponse.json({
imageUrl: result.imageUrl,
text: "", // BytePlus doesn't generate text
usage: result.usage
})
Replace Gemini-specific log messages:
// OLD
console.log("[v0] Gemini API key available:", !!process.env.GEMINI_API_KEY)
console.log("[v0] Calling Gemini API...")
// NEW
console.log("[v0] BytePlus API key available:", !!process.env.BYTEPLUS_API_KEY)
console.log("[v0] Calling BytePlus SeeDream v4.5 API...")
Remove Gemini SDK from project dependencies.
npm uninstall @google/genai
This automatically updates package.json and package-lock.json.
Check that Gemini is no longer referenced:
grep -i "genai\|gemini" package.json
Expected: No matches (empty output).
npm install
npx tsc --noEmit # Verify no type errors
See references/testing-checklist.md for comprehensive testing guide.
Quick validation:
npm run validatenpx tsc --noEmitnpm run lintnpm run buildTest scenarios:
Update all documentation to reflect BytePlus instead of Gemini.
Files to update:
Search for remaining references:
grep -ri "gemini\|google ai" *.md docs/*.md
See references/api-comparison.md for detailed parameter mapping.
Quick comparison:
| Aspect | Gemini 2.5 Flash | BytePlus SeeDream v4.5 |
|---|---|---|
| Integration | SDK (@google/genai) | REST API (native fetch) |
| Auth | API key in constructor | Bearer token in header |
| Image input | Base64 in inlineData | Data URI in image array |
| Resolution | Aspect ratio (4:5) | Exact pixels (2048x2560) |
| Response | candidates[].content.parts[] | data[0].b64_json |
| Text output | Supported | Not supported |
See references/troubleshooting.md for detailed solutions.
Common mistakes:
data:image/png;base64,... not plain base64seedream-4-5-251128 not seedream-4.5import { GoogleGenAI } from "@google/genai"
const genAI = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY! })
const result = await genAI.models.generateContent({
model: "gemini-2.5-flash-image",
contents: [{
role: "user",
parts: [
{ text: prompt },
{ inlineData: { mimeType, data: base64String } }
]
}],
config: {
responseModalities: ["IMAGE"],
imageConfig: { aspectRatio: "4:5" }
}
})
import { generateImageWithByteplus } from "@/lib/byteplus-client"
const result = await generateImageWithByteplus({
prompt: prompt,
images: [{ data: base64String, mimeType: "image/png" }]
})
if (result.error) {
// Handle error
}
See references/error-handling.md for comprehensive guide.
HTTP Status Codes:
400 - Invalid request (check image format, size, aspect ratio)401 - Authentication failed (invalid API key)429 - Rate limit exceeded (implement backoff)500 - Service error (retry with exponential backoff)Example error handler:
if (!response.ok) {
switch (response.status) {
case 400:
return { error: "Invalid image or prompt" }
case 401:
return { error: "BytePlus API authentication failed" }
case 429:
return { error: "Rate limit exceeded, please try again later" }
case 500:
return { error: "BytePlus service error, please retry" }
default:
return { error: "Failed to generate image" }
}
}
Migration complete when:
npx tsc --noEmit)npm run lint)For common issues and solutions, see references/troubleshooting.md.
For API parameter details, see references/api-comparison.md.
For comprehensive testing checklist, see references/testing-checklist.md.