- OpenAIUpdated
- OpenAI: AdvancedNew
- AnthropicUpdated
- Anthropic: AdvancedNew
- Google GeminiUpdated
- Google Gemini: AdvancedNew
- Google Vertex AIUpdated
- OllamaUpdated
- Grok (xAI)Updated
- GroqUpdated
- MistralUpdated
- CohereUpdated
- TypeSafeUpdated
- OllayaUpdated
- ElevenLabsUpdated
- fal.aiUpdated
- ReactorUpdated
- World LabsUpdated
- OpenRouter AdapterUpdated
- OpenRouter: AdvancedNew
- Perplexity SearchUpdated
- Vercel AI GatewayUpdated
- Lovable AI GatewayUpdated
- OpenAI-CompatibleUpdated
- OpenAI-Compatible: AdvancedNew
- LLM GatewayUpdated
- CloudflareUpdated
- Claude CodeUpdated
- CodexUpdated
- OpenCodeUpdated
- Grok BuildUpdated
- ACP-CompatibleUpdated
- Amazon BedrockUpdated
- BytePlusUpdated
- BytePlus: AdvancedNew
BytePlus
@tanstack/ai-byteplus calls Seed chat models with reasoning, plus Seedance video, Seedream images, and Seed Speech.
1. Install#
npm i @tanstack/ai-bytepluspnpm add @tanstack/ai-byteplusyarn add @tanstack/ai-byteplusbun add @tanstack/ai-byteplus2. Set the API keys#
BytePlus sells these models as two products, and each product has its own key. Put both keys in the environment of your server:
# ModelArk: chat, Seedance video, Seedream images
ARK_API_KEY=...
# Seed Speech: text-to-speech and transcription
BYTEPLUS_VOICE_API_KEY=...- byteplusText, byteplusVideo, and byteplusImage read ARK_API_KEY. If it is not set, they read BYTEPLUS_API_KEY.
- byteplusSpeech and byteplusTranscription read BYTEPLUS_VOICE_API_KEY. An Ark key fails here with 45000010 Invalid X-Api-Key.
To pass the key in code, use the create* factory of the same adapter:
import { createBytePlusText } from "@tanstack/ai-byteplus";
const adapter = createBytePlusText("dola-seed-2-1-turbo-260628", process.env.ARK_API_KEY!);Ark keys work in one region only. The default endpoint is Asia-Pacific south-east. For a key from another region, see Regions.
3. Stream a chat from the server#
import {
chat,
chatParamsFromRequest,
toServerSentEventsResponse,
} from "@tanstack/ai";
import { byteplusText } from "@tanstack/ai-byteplus";
export async function POST(request: Request) {
const { messages, threadId, runId } = await chatParamsFromRequest(request);
const stream = chat({
adapter: byteplusText("dola-seed-2-1-turbo-260628"),
messages,
threadId,
runId,
});
return toServerSentEventsResponse(stream);
}4. Render the chat#
The client is the same for every provider. Point useChat at your route:
import { useState } from "react";
import { useChat, fetchServerSentEvents } from "@tanstack/ai-react";
export function Chat() {
const [input, setInput] = useState("");
const { messages, sendMessage } = useChat({
connection: fetchServerSentEvents("/api/chat"),
threadId: "support-chat",
});
return (
<form
onSubmit={(event) => {
event.preventDefault();
sendMessage(input);
setInput("");
}}
>
{messages.map((message) => (
<p key={message.id}>
{message.parts
.map((part) => (part.type === "text" ? part.content : ""))
.join("")}
</p>
))}
<input value={input} onChange={(event) => setInput(event.target.value)} />
</form>
);
}For Vue, Solid, Svelte, Angular, and the other frameworks, see Quick Start.
You now have a streaming chat on BytePlus. Seed models think before they answer, and useChat shows that thinking as separate thinking parts. Tools work the same as with every adapter. BytePlus has no provider tools of its own.
Video generation (Seedance)#
Video generation is an experimental feature.
Seedance runs as a job. generateVideo() starts the job and returns a jobId. Poll the job until it has a video URL:
import { generateVideo, getVideoJobStatus } from "@tanstack/ai";
import { byteplusVideo } from "@tanstack/ai-byteplus";
const adapter = byteplusVideo("dreamina-seedance-2-5-260628");
const { jobId } = await generateVideo({
adapter,
prompt: "a guitar being played in a store",
threadId: "thread-1",
size: "16:9_720p",
duration: 5,
});
let status = await getVideoJobStatus({ adapter, jobId });
while (status.status === "pending" || status.status === "processing") {
await new Promise((resolve) => setTimeout(resolve, 5000));
status = await getVideoJobStatus({ adapter, jobId });
}
console.log(status.status === "completed" ? status.url : status.error);- The video URL expires 24 hours after the job completes. If you want to keep the video, download it. See Keeping generated files.
- size is a ratio ("16:9") or a ratio with a resolution ("16:9_720p"). The ratios are 16:9, 9:16, 4:3, 3:4, 1:1, 21:9, and adaptive.
- The Seedance 2 models can need activation in the Ark Console first. Until then, a call fails with 404 ModelNotOpen.
To run the job from a React component, and for the options of each model, see BytePlus: Advanced.
Image generation (Seedream)#
import { generateImage } from "@tanstack/ai";
import { byteplusImage } from "@tanstack/ai-byteplus";
const result = await generateImage({
adapter: byteplusImage("dola-seedream-5-0-pro-260628"),
prompt: "a guitar being played in a store",
threadId: "thread-1",
size: "2K",
modelOptions: { watermark: false },
});
console.log(result.images[0]?.url);- watermark is true by default. BytePlus then writes "AI generated" in the bottom-right corner. Set watermark: false to stop this.
- size is a token (1K, 2K, 4K) or pixels (2048x2048). Do not mix the two.
- numberOfImages is a maximum, not an exact count. The model decides how many images to return.
- Result URLs expire after 24 hours. To get the bytes in the response, set response_format: "b64_json" in modelOptions.
To edit an existing image, see Seedream reference images.
Text-to-speech (Seed Speech)#
This adapter uses BYTEPLUS_VOICE_API_KEY:
import { generateSpeech } from "@tanstack/ai";
import { byteplusSpeech } from "@tanstack/ai-byteplus";
const result = await generateSpeech({
adapter: byteplusSpeech("seed-audio-1.0"),
text: "welcome to the guitar store",
threadId: "thread-1",
voice: "en_female_stokie_uranus_bigtts",
format: "mp3",
});
console.log(result.contentType, result.audio.length);- Formats: wav, mp3, pcm, and ogg_opus.
- One request makes 120 seconds of audio at most.
- timestamps: true gives you word timings, and turns makes a dialogue with up to three voices.
The voice ids, voice cloning, timings, dialogue, and watermarks are in Seed Speech. The client half is the standard useGenerateSpeech hook.
Transcription (Seed Speech ASR)#
This adapter also uses BYTEPLUS_VOICE_API_KEY. The call is synchronous, so you get the transcript back with no polling:
import { generateTranscription } from "@tanstack/ai";
import { byteplusTranscription } from "@tanstack/ai-byteplus";
const result = await generateTranscription({
adapter: byteplusTranscription("seed-asr"),
audio: "https://example.com/recording.mp3",
modelOptions: { enable_punc: true, enable_speaker_info: true },
threadId: "thread-1",
});
console.log(result.text);
for (const segment of result.segments ?? []) {
console.log(segment.speaker, segment.text);
}audio takes a File, base64, a data URL, or a public URL. The limit is two hours and 100 MB. For the other options, see Transcription options.
Models and options#
Model options#
Ark speaks the OpenAI chat format, so the sampling options keep their OpenAI names. They go in modelOptions:
import { chat } from "@tanstack/ai";
import { byteplusText } from "@tanstack/ai-byteplus";
const stream = chat({
adapter: byteplusText("dola-seed-2-1-turbo-260628"),
messages: [{ role: "user", content: "Hello!" }],
threadId: "thread-1",
modelOptions: {
temperature: 0.7,
top_p: 0.9,
max_tokens: 2048,
},
});- Send max_tokens or max_completion_tokens, not both. Ark returns a 400 when you send both. The types cannot catch this.
- repetition_penalty and service_tier are Ark options. service_tier: "flex" sends the request to a cheaper batch queue with no latency guarantee.
Need a header on each request, or a log of each model call? The chat adapter supports wrapFetch.
Reasoning#
Seed models think by default. Set how hard they think with reasoning on chat():
import { chat } from "@tanstack/ai";
import { byteplusText } from "@tanstack/ai-byteplus";
const stream = chat({
adapter: byteplusText("glm-5-2-260617"),
messages: [{ role: "user", content: "Hello!" }],
threadId: "thread-1",
reasoning: "off",
});The levels of each model:
- dola-seed-2-1-turbo-260628 and the seed-* models: minimal to high. They cannot stop thinking.
- glm-5-2-260617: off to high.
- glm-4-7-251222, deepseek-v3-2-251201: off, high.
- deepseek-v4-pro-260425, deepseek-v4-flash-260425: off, high, max.
- gpt-oss-120b-250805: low, medium, high.
What goes over the wire, and how the adapter keeps the encrypted_content of the reasoning, is in Reasoning and encrypted_content.
Structured output#
Ten of the 18 chat models support chat({ outputSchema }). Use dola-seed-2-1-turbo-260628 or seed-2-0-lite-260228. On the other models, the call fails with an error that names the models that work. See Structured output.
Models#
Newest first. The package exports the full lists: BYTEPLUS_CHAT_MODELS, BYTEPLUS_VIDEO_MODELS, BYTEPLUS_IMAGE_MODELS, BYTEPLUS_TTS_MODELS, and BYTEPLUS_TRANSCRIPTION_MODELS.
| Activity | Factory | Models |
|---|---|---|
| Chat | byteplusText | dola-seed-2-1-turbo-260628, seed-2-0-lite-260428, seed-2-0-mini-260428, seed-2-0-pro-260328, seed-2-0-lite-260228, seed-2-0-mini-260215, seed-2-0-code-preview-260328, seed-1-8-251228, seed-1-6-250915, seed-1-6-250615, seed-1-6-flash-250715, seed-1-6-flash-250615, glm-5-2-260617, glm-4-7-251222, deepseek-v4-pro-260425, deepseek-v4-flash-260425, deepseek-v3-2-251201, gpt-oss-120b-250805 |
| Video | byteplusVideo | dreamina-seedance-2-5-260628, dreamina-seedance-2-0-260128, dreamina-seedance-2-0-fast-260128, dreamina-seedance-2-0-mini-260615, seedance-1-5-pro-251215, seedance-1-0-pro-250528, seedance-1-0-pro-fast-251015 |
| Images | byteplusImage | dola-seedream-5-0-pro-260628, seedream-5-0-260128, seedream-5-0-lite-260128, seedream-4-5-251128, seedream-4-0-250828 |
| Speech | byteplusSpeech | seed-audio-1.0 |
| Transcription | byteplusTranscription | seed-asr |
BytePlus retires model ids often, and its published lists contain ids that do not work. This package lists only dated ids that answered a live request.
adapter.inputModalities lists the input kinds of the selected model. See Check what a model accepts.
Advanced#
These topics are on BytePlus: Advanced:
- Regions, and the two BYOK providers.
- Reasoning, encrypted_content, and structured output.
- Seedance from the client, the options of each model, and Seedance 2.5.
- Seedream reference images, Seed Speech details, and transcription options.
- The API reference.