@tanstack/ai-byteplus 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +202 -0
- package/dist/esm/adapters/image.d.ts +89 -0
- package/dist/esm/adapters/image.js +229 -0
- package/dist/esm/adapters/image.js.map +1 -0
- package/dist/esm/adapters/text.d.ts +163 -0
- package/dist/esm/adapters/text.js +347 -0
- package/dist/esm/adapters/text.js.map +1 -0
- package/dist/esm/adapters/transcription.d.ts +102 -0
- package/dist/esm/adapters/transcription.js +274 -0
- package/dist/esm/adapters/transcription.js.map +1 -0
- package/dist/esm/adapters/tts.d.ts +143 -0
- package/dist/esm/adapters/tts.js +307 -0
- package/dist/esm/adapters/tts.js.map +1 -0
- package/dist/esm/adapters/video.d.ts +182 -0
- package/dist/esm/adapters/video.js +442 -0
- package/dist/esm/adapters/video.js.map +1 -0
- package/dist/esm/audio/transcription-provider-options.d.ts +46 -0
- package/dist/esm/audio/tts-provider-options.d.ts +114 -0
- package/dist/esm/audio/wire-types.d.ts +261 -0
- package/dist/esm/audio/wire-types.js +28 -0
- package/dist/esm/audio/wire-types.js.map +1 -0
- package/dist/esm/image/image-provider-options.d.ts +165 -0
- package/dist/esm/image/image-provider-options.js +134 -0
- package/dist/esm/image/image-provider-options.js.map +1 -0
- package/dist/esm/image/wire-types.d.ts +149 -0
- package/dist/esm/index.d.ts +25 -0
- package/dist/esm/index.js +11 -0
- package/dist/esm/message-types.d.ts +154 -0
- package/dist/esm/model-meta.d.ts +594 -0
- package/dist/esm/model-meta.js +619 -0
- package/dist/esm/model-meta.js.map +1 -0
- package/dist/esm/text/text-provider-options.d.ts +109 -0
- package/dist/esm/utils/client.d.ts +183 -0
- package/dist/esm/utils/client.js +253 -0
- package/dist/esm/utils/client.js.map +1 -0
- package/dist/esm/video/video-provider-options.d.ts +197 -0
- package/dist/esm/video/video-provider-options.js +191 -0
- package/dist/esm/video/video-provider-options.js.map +1 -0
- package/dist/esm/video/wire-types.d.ts +248 -0
- package/package.json +77 -0
- package/src/adapters/image.ts +409 -0
- package/src/adapters/text.ts +539 -0
- package/src/adapters/transcription.ts +479 -0
- package/src/adapters/tts.ts +447 -0
- package/src/adapters/video.ts +732 -0
- package/src/audio/transcription-provider-options.ts +46 -0
- package/src/audio/tts-provider-options.ts +122 -0
- package/src/audio/wire-types.ts +290 -0
- package/src/image/image-provider-options.ts +288 -0
- package/src/image/wire-types.ts +169 -0
- package/src/index.ts +222 -0
- package/src/message-types.ts +169 -0
- package/src/model-meta.ts +954 -0
- package/src/text/text-provider-options.ts +151 -0
- package/src/utils/client.ts +377 -0
- package/src/video/video-provider-options.ts +361 -0
- package/src/video/wire-types.ts +293 -0
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider options and per-model capability tables for the BytePlus Seedance
|
|
3
|
+
* video models.
|
|
4
|
+
*
|
|
5
|
+
* Every applicability claim below was probed live against
|
|
6
|
+
* `https://ark.ap-southeast.bytepluses.com/api/v3` on 2026-07-31. The probe
|
|
7
|
+
* sent an out-of-range `seed` alongside the field under test, so requests that
|
|
8
|
+
* passed validation still failed before a task was created (nothing billed):
|
|
9
|
+
* an error naming the field under test means "rejected", an error naming
|
|
10
|
+
* `seed` means "accepted". Ark reports only one arbitrary invalid parameter
|
|
11
|
+
* per request, so each cell was retried until a verdict repeated.
|
|
12
|
+
*
|
|
13
|
+
* Ark rejects an inapplicable field outright — "the specified parameter
|
|
14
|
+
* `draft` is not supported for model seedance-1-0-pro in t2v, must be empty" —
|
|
15
|
+
* so these tables are not cosmetic: sending a field to the wrong model is a
|
|
16
|
+
* 400, not a no-op.
|
|
17
|
+
*
|
|
18
|
+
* **Where the adapter guards, and where it doesn't** (deliberate, not an
|
|
19
|
+
* oversight). Scalar applicability — `service_tier`, `draft`, `priority`,
|
|
20
|
+
* `frames`, `camera_fixed` — is left to Ark, whose 400 names the offending
|
|
21
|
+
* field and the model precisely enough to act on, and whose per-model rules
|
|
22
|
+
* shift as BytePlus ships models. Duplicating that here would mean a table
|
|
23
|
+
* that silently goes stale and starts rejecting requests the API would have
|
|
24
|
+
* accepted. The adapter guards locally only where the API's own error is
|
|
25
|
+
* misleading or arrives too late to be actionable: prompt media shape (role
|
|
26
|
+
* vocabulary, frame-vs-reference exclusivity, frame cardinality) and the
|
|
27
|
+
* resolution tier, both of which are derived from a caller's `prompt` /
|
|
28
|
+
* `size` rather than passed through verbatim.
|
|
29
|
+
*
|
|
30
|
+
* @experimental Video generation is an experimental feature and may change.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { isKnownBytePlusVideoModel } from '../model-meta'
|
|
34
|
+
import type {
|
|
35
|
+
BytePlusVideoModel,
|
|
36
|
+
BytePlusVideoModelOrString,
|
|
37
|
+
BytePlusVideoRatio,
|
|
38
|
+
BytePlusVideoResolution,
|
|
39
|
+
} from '../model-meta'
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Inference queue for the request.
|
|
43
|
+
*
|
|
44
|
+
* - `default` — online inference: lower RPM and concurrency quotas, lowest
|
|
45
|
+
* latency.
|
|
46
|
+
* - `flex` — offline batch inference: higher daily token quotas at half the
|
|
47
|
+
* price, with no latency guarantee. Task ids come back with a `cgt-batch-`
|
|
48
|
+
* prefix (live-verified).
|
|
49
|
+
*
|
|
50
|
+
* Only the Seedance 1.x models accept this field. The Seedance 2.0 family
|
|
51
|
+
* rejects it ("service_tier is not supported … must be empty").
|
|
52
|
+
*
|
|
53
|
+
* @experimental Video generation is an experimental feature and may change.
|
|
54
|
+
*/
|
|
55
|
+
export type BytePlusVideoServiceTier = 'default' | 'flex'
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Provider-specific options for Seedance video generation. These map one-to-one
|
|
59
|
+
* onto the create-task request body and take precedence over the values the
|
|
60
|
+
* adapter derives from the generic `size` / `duration` options.
|
|
61
|
+
*
|
|
62
|
+
* Fields are model-dependent; each one documents where it applies. Passing a
|
|
63
|
+
* field to a model that does not accept it is a 400 from Ark, not a silent
|
|
64
|
+
* ignore.
|
|
65
|
+
*
|
|
66
|
+
* @experimental Video generation is an experimental feature and may change.
|
|
67
|
+
*/
|
|
68
|
+
export interface BytePlusVideoProviderOptions {
|
|
69
|
+
/**
|
|
70
|
+
* Output aspect ratio. Overrides the ratio half of the generic `size`.
|
|
71
|
+
*
|
|
72
|
+
* `adaptive` (follow the input frame) is the default on Seedance 2.0 and
|
|
73
|
+
* 1.5-pro but is rejected by Seedance 1.0-pro / 1.0-pro-fast for
|
|
74
|
+
* text-to-video.
|
|
75
|
+
*/
|
|
76
|
+
ratio?: BytePlusVideoRatio
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Output resolution tier. Overrides the resolution half of the generic
|
|
80
|
+
* `size`. Matched case-insensitively by the API; this package uses
|
|
81
|
+
* lowercase throughout. `4k` exists only on `dreamina-seedance-2-0-260128`,
|
|
82
|
+
* and there is no 2K tier on any model.
|
|
83
|
+
*/
|
|
84
|
+
resolution?: BytePlusVideoResolution
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Whole seconds of output. Overrides the generic `duration`, and unlike it
|
|
88
|
+
* is sent verbatim rather than snapped into the model's range.
|
|
89
|
+
*
|
|
90
|
+
* `-1` asks the model to choose its own length; accepted by Seedance 2.0
|
|
91
|
+
* and 1.5-pro only.
|
|
92
|
+
*/
|
|
93
|
+
duration?: number
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Frame count instead of `duration`, for fractional-second output. Takes
|
|
97
|
+
* precedence over `duration` server-side. Valid values are the integers of
|
|
98
|
+
* the form `25 + 4n` within `[29, 289]`, at 24 fps.
|
|
99
|
+
*
|
|
100
|
+
* Seedance 1.0-pro and 1.0-pro-fast only.
|
|
101
|
+
*/
|
|
102
|
+
frames?: number
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Randomness seed, an integer in `[-1, 2^32-1]`. `-1` (the default) leaves
|
|
106
|
+
* generation unseeded. Accepted by every Seedance model.
|
|
107
|
+
*/
|
|
108
|
+
seed?: number
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Appends a "fix the camera" instruction to the prompt. Best-effort — the
|
|
112
|
+
* model is not constrained to obey it.
|
|
113
|
+
*
|
|
114
|
+
* Seedance 1.5-pro, 1.0-pro and 1.0-pro-fast only; the 2.0 family rejects
|
|
115
|
+
* it.
|
|
116
|
+
*/
|
|
117
|
+
camera_fixed?: boolean
|
|
118
|
+
|
|
119
|
+
/** Burn a watermark into the output. Defaults to `false`. */
|
|
120
|
+
watermark?: boolean
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Generate an audio track synchronized with the visuals — dialogue, effects
|
|
124
|
+
* and score inferred from the prompt. Quote dialogue in the prompt for
|
|
125
|
+
* better results.
|
|
126
|
+
*
|
|
127
|
+
* Accepted by every model at the API's validation layer, but only Seedance
|
|
128
|
+
* 2.0 and 1.5-pro actually produce audio.
|
|
129
|
+
*/
|
|
130
|
+
generate_audio?: boolean
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Inference queue. Seedance 1.x only — the 2.0 family has no offline tier.
|
|
134
|
+
*/
|
|
135
|
+
service_tier?: BytePlusVideoServiceTier
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Also return the video's final frame as a watermark-free PNG, readable from
|
|
139
|
+
* the finished task as `content.last_frame_url`. Chain it into the next
|
|
140
|
+
* task's first frame to extend a shot. Accepted by every model.
|
|
141
|
+
*/
|
|
142
|
+
return_last_frame?: boolean
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Render a cheap, low-fidelity preview to sanity-check staging and camera
|
|
146
|
+
* work before paying for the real thing.
|
|
147
|
+
*
|
|
148
|
+
* Seedance 1.5-pro only.
|
|
149
|
+
*/
|
|
150
|
+
draft?: boolean
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Queue priority, `[0, 9]`. Seedance 2.0 family only — 1.5-pro rejects it,
|
|
154
|
+
* and the 1.0 models accept it without acting on it.
|
|
155
|
+
*/
|
|
156
|
+
priority?: number
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Seconds after `created_at` at which an unfinished task is abandoned and
|
|
160
|
+
* marked `expired`. Documented range `[3600, 259200]`, default 172800
|
|
161
|
+
* (48 hours). The floor is enforced on Seedance 1.x but not on the 2.0
|
|
162
|
+
* family.
|
|
163
|
+
*/
|
|
164
|
+
execution_expires_after?: number
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* URL that receives a POST with the full task payload on every status
|
|
168
|
+
* change. BytePlus retries a failed delivery three times.
|
|
169
|
+
*/
|
|
170
|
+
callback_url?: string
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Stable opaque identifier for the end user driving the request, for abuse
|
|
174
|
+
* attribution. Max 64 characters — hash the real identifier rather than
|
|
175
|
+
* sending it.
|
|
176
|
+
*/
|
|
177
|
+
safety_identifier?: string
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Type-only map from video model name to its provider options. Seedance takes
|
|
182
|
+
* the same option surface across models; applicability is per-field and
|
|
183
|
+
* documented on {@link BytePlusVideoProviderOptions}.
|
|
184
|
+
*
|
|
185
|
+
* @experimental Video generation is an experimental feature and may change.
|
|
186
|
+
*/
|
|
187
|
+
export type BytePlusVideoModelProviderOptionsByName = {
|
|
188
|
+
[K in BytePlusVideoModel]: BytePlusVideoProviderOptions
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Aspect ratios accepted by the create endpoint.
|
|
193
|
+
*
|
|
194
|
+
* `adaptive` is rejected by Seedance 1.0-pro / 1.0-pro-fast for text-to-video
|
|
195
|
+
* but is the documented default for their image-to-video path, so it is not
|
|
196
|
+
* filtered per model here.
|
|
197
|
+
*/
|
|
198
|
+
const BYTEPLUS_VIDEO_RATIOS: ReadonlyArray<string> = [
|
|
199
|
+
'16:9',
|
|
200
|
+
'9:16',
|
|
201
|
+
'4:3',
|
|
202
|
+
'3:4',
|
|
203
|
+
'1:1',
|
|
204
|
+
'21:9',
|
|
205
|
+
'adaptive',
|
|
206
|
+
]
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Resolutions each model accepts, live-probed.
|
|
210
|
+
*
|
|
211
|
+
* Two findings here contradict the BytePlus prose docs and are worth calling
|
|
212
|
+
* out: there is no 2K tier on any Seedance model (`2k`/`2K` is rejected
|
|
213
|
+
* everywhere, including on the 2.0 flagship whose docs advertise "up to 4K"),
|
|
214
|
+
* and `seedance-1-0-pro-fast-251015` does accept `1080p` despite being
|
|
215
|
+
* documented as 480p/720p only.
|
|
216
|
+
*/
|
|
217
|
+
const BYTEPLUS_VIDEO_RESOLUTIONS: {
|
|
218
|
+
readonly [K in BytePlusVideoModel]: ReadonlyArray<BytePlusVideoResolution>
|
|
219
|
+
} = {
|
|
220
|
+
'dreamina-seedance-2-0-260128': ['480p', '720p', '1080p', '4k'],
|
|
221
|
+
'dreamina-seedance-2-0-fast-260128': ['480p', '720p'],
|
|
222
|
+
'dreamina-seedance-2-0-mini-260615': ['480p', '720p'],
|
|
223
|
+
'seedance-1-5-pro-251215': ['480p', '720p', '1080p'],
|
|
224
|
+
'seedance-1-0-pro-250528': ['480p', '720p', '1080p'],
|
|
225
|
+
'seedance-1-0-pro-fast-251015': ['480p', '720p', '1080p'],
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Models accepting reference-media mode (`r2v`): reference images, video and
|
|
230
|
+
* audio that the output draws on without pinning specific frames. The 1.x
|
|
231
|
+
* models reject it with "the specified task_type r2v does not support model …".
|
|
232
|
+
*/
|
|
233
|
+
const BYTEPLUS_VIDEO_REFERENCE_MEDIA_MODELS: ReadonlySet<string> = new Set([
|
|
234
|
+
'dreamina-seedance-2-0-260128',
|
|
235
|
+
'dreamina-seedance-2-0-fast-260128',
|
|
236
|
+
'dreamina-seedance-2-0-mini-260615',
|
|
237
|
+
])
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Models accepting a closing frame (`flf2v`, first-and-last-frame mode).
|
|
241
|
+
* `seedance-1-0-pro-fast-251015` is the one Seedance model without it — it
|
|
242
|
+
* does text-to-video and single-first-frame image-to-video only.
|
|
243
|
+
*/
|
|
244
|
+
const BYTEPLUS_VIDEO_LAST_FRAME_MODELS: ReadonlySet<string> = new Set([
|
|
245
|
+
'dreamina-seedance-2-0-260128',
|
|
246
|
+
'dreamina-seedance-2-0-fast-260128',
|
|
247
|
+
'dreamina-seedance-2-0-mini-260615',
|
|
248
|
+
'seedance-1-5-pro-251215',
|
|
249
|
+
'seedance-1-0-pro-250528',
|
|
250
|
+
])
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* True when the model is *known* to support reference-media mode (reference
|
|
254
|
+
* images, video and audio). An id this package has no metadata for answers
|
|
255
|
+
* `false`; callers must decide whether that means "no" or "unknown" — the
|
|
256
|
+
* adapter treats it as unknown and lets Ark rule.
|
|
257
|
+
*
|
|
258
|
+
* @experimental Video generation is an experimental feature and may change.
|
|
259
|
+
*/
|
|
260
|
+
export function supportsReferenceMedia(model: string): boolean {
|
|
261
|
+
return BYTEPLUS_VIDEO_REFERENCE_MEDIA_MODELS.has(model)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* True when the model is *known* to support pinning the video's closing
|
|
266
|
+
* frame. Same unknown-id caveat as {@link supportsReferenceMedia}.
|
|
267
|
+
*
|
|
268
|
+
* @experimental Video generation is an experimental feature and may change.
|
|
269
|
+
*/
|
|
270
|
+
export function supportsLastFrame(model: string): boolean {
|
|
271
|
+
return BYTEPLUS_VIDEO_LAST_FRAME_MODELS.has(model)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Splits a `size` template into its Seedance request fields.
|
|
276
|
+
*
|
|
277
|
+
* The template is either a bare aspect ratio (`'16:9'`) or
|
|
278
|
+
* `ratio_resolution` (`'16:9_720p'`), mirroring the grok video adapter.
|
|
279
|
+
* Returns `undefined` when the string doesn't match the template at all.
|
|
280
|
+
*
|
|
281
|
+
* The resolution half comes back lowercased. Ark itself matches the field
|
|
282
|
+
* case-insensitively, but this package standardizes on lowercase so callers
|
|
283
|
+
* can compare the result against {@link BytePlusVideoResolution} directly.
|
|
284
|
+
*
|
|
285
|
+
* @experimental Video generation is an experimental feature and may change.
|
|
286
|
+
*/
|
|
287
|
+
export function parseBytePlusVideoSize(
|
|
288
|
+
size: string,
|
|
289
|
+
): { ratio: string; resolution?: string } | undefined {
|
|
290
|
+
const match = /^(\d+:\d+|adaptive)(?:_(.+))?$/.exec(size)
|
|
291
|
+
const [, ratio, resolution] = match ?? []
|
|
292
|
+
if (ratio === undefined) return undefined
|
|
293
|
+
return {
|
|
294
|
+
ratio,
|
|
295
|
+
...(resolution !== undefined && { resolution: resolution.toLowerCase() }),
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Validates a resolution against a model's tiers, returning it lowercased.
|
|
301
|
+
*
|
|
302
|
+
* Used for both halves of the request: the resolution parsed out of the
|
|
303
|
+
* generic `size`, and a `modelOptions.resolution` that overrides it. A model
|
|
304
|
+
* this package has no table for is normalized but not checked — see
|
|
305
|
+
* {@link BytePlusVideoModelOrString}.
|
|
306
|
+
*
|
|
307
|
+
* @throws Error when a known model does not offer the tier.
|
|
308
|
+
*
|
|
309
|
+
* @experimental Video generation is an experimental feature and may change.
|
|
310
|
+
*/
|
|
311
|
+
export function resolveBytePlusVideoResolution(
|
|
312
|
+
model: BytePlusVideoModelOrString,
|
|
313
|
+
resolution: string,
|
|
314
|
+
): string {
|
|
315
|
+
const normalized = resolution.toLowerCase()
|
|
316
|
+
if (!isKnownBytePlusVideoModel(model)) return normalized
|
|
317
|
+
|
|
318
|
+
const allowed = BYTEPLUS_VIDEO_RESOLUTIONS[model]
|
|
319
|
+
if (!allowed.includes(normalized as BytePlusVideoResolution)) {
|
|
320
|
+
throw new Error(
|
|
321
|
+
`byteplus: resolution "${resolution}" is not supported by model ` +
|
|
322
|
+
`"${model}". Supported resolutions: ${allowed.join(', ')}.`,
|
|
323
|
+
)
|
|
324
|
+
}
|
|
325
|
+
return normalized
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Validates a `size` template against a model and returns the request fields
|
|
330
|
+
* it maps onto, with the resolution lowercased.
|
|
331
|
+
*
|
|
332
|
+
* For an unknown model only the template's *shape* is checked — enough to
|
|
333
|
+
* split it into `ratio` and `resolution` — because a future model may bring
|
|
334
|
+
* ratios and tiers that do not exist today. Ark validates the values.
|
|
335
|
+
*
|
|
336
|
+
* @throws Error when the template is malformed, or (known models only) the
|
|
337
|
+
* ratio is unknown or the resolution is not offered by this model.
|
|
338
|
+
*
|
|
339
|
+
* @experimental Video generation is an experimental feature and may change.
|
|
340
|
+
*/
|
|
341
|
+
export function resolveBytePlusVideoSize(
|
|
342
|
+
model: BytePlusVideoModelOrString,
|
|
343
|
+
size: string,
|
|
344
|
+
): { ratio: string; resolution?: string } {
|
|
345
|
+
const parsed = parseBytePlusVideoSize(size)
|
|
346
|
+
const known = isKnownBytePlusVideoModel(model)
|
|
347
|
+
if (!parsed || (known && !BYTEPLUS_VIDEO_RATIOS.includes(parsed.ratio))) {
|
|
348
|
+
throw new Error(
|
|
349
|
+
`byteplus: size "${size}" is not supported by model "${model}". Expected ` +
|
|
350
|
+
`"ratio" or "ratio_resolution" (e.g. "16:9_720p") with ratio one of: ` +
|
|
351
|
+
`${BYTEPLUS_VIDEO_RATIOS.join(', ')}.`,
|
|
352
|
+
)
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return {
|
|
356
|
+
ratio: parsed.ratio,
|
|
357
|
+
...(parsed.resolution !== undefined && {
|
|
358
|
+
resolution: resolveBytePlusVideoResolution(model, parsed.resolution),
|
|
359
|
+
}),
|
|
360
|
+
}
|
|
361
|
+
}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire types for the BytePlus Ark Seedance video task API
|
|
3
|
+
* (`/contents/generations/tasks`).
|
|
4
|
+
*
|
|
5
|
+
* Hand-written minimal shapes covering only the fields this adapter sends and
|
|
6
|
+
* reads, with provenance noted inline. Three sources:
|
|
7
|
+
*
|
|
8
|
+
* 1. The harvested OpenAPI 3.1 documents for the `ark` service, actions
|
|
9
|
+
* `CreateContentsGenerationsTasks` (`x-updated-time: 2026-05-07`),
|
|
10
|
+
* `GetContentsGenerationsTask` (`2026-04-14`),
|
|
11
|
+
* `ListContentsGenerationsTasks` (`2026-03-24`) and
|
|
12
|
+
* `DeleteContentsGenerationsTasks` — authoritative for field names,
|
|
13
|
+
* defaults and response shapes.
|
|
14
|
+
* 2. Live calls against `https://ark.ap-southeast.bytepluses.com/api/v3` on
|
|
15
|
+
* 2026-07-31 with a real `ARK_API_KEY`, which pinned the create response,
|
|
16
|
+
* the per-model parameter applicability (see
|
|
17
|
+
* `video-provider-options.ts`) and the `content[]` role vocabulary.
|
|
18
|
+
* 3. The Seedance prose docs, for the retention windows.
|
|
19
|
+
*
|
|
20
|
+
* Two casing traps worth knowing: the response frame-rate field is
|
|
21
|
+
* `framespersecond` (all lowercase, no underscores), and `resolution` is
|
|
22
|
+
* matched case-insensitively on the way in (`4K`, `4k` and even `1080P` are
|
|
23
|
+
* all accepted — live-verified), so this package standardizes on lowercase.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Task lifecycle states.
|
|
28
|
+
*
|
|
29
|
+
* `queued` and `running` are non-terminal; the rest are terminal. `cancelled`
|
|
30
|
+
* records are dropped 24 hours after cancellation, and only a `queued` task
|
|
31
|
+
* can be cancelled at all.
|
|
32
|
+
*
|
|
33
|
+
* Source: `GetContentsGenerationsTask` / `ListContentsGenerationsTasks`
|
|
34
|
+
* `status` descriptions. (The Get document omits `expired` from its list
|
|
35
|
+
* while the List document includes it; `execution_expires_after` is documented
|
|
36
|
+
* as producing `expired` on both, so it is included here.)
|
|
37
|
+
*/
|
|
38
|
+
export type BytePlusVideoTaskStatus =
|
|
39
|
+
| 'queued'
|
|
40
|
+
| 'running'
|
|
41
|
+
| 'succeeded'
|
|
42
|
+
| 'failed'
|
|
43
|
+
| 'cancelled'
|
|
44
|
+
| 'expired'
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Role of a media item inside `content[]`.
|
|
48
|
+
*
|
|
49
|
+
* Live-verified: an unknown role is rejected with "invalid role specified for
|
|
50
|
+
* image content", and the API sorts requests into task types from the roles
|
|
51
|
+
* present — `i2v` (first frame), `flf2v` (first + last frame) and `r2v`
|
|
52
|
+
* (reference media). The two families are mutually exclusive: mixing them
|
|
53
|
+
* fails with "first/last frame content cannot be mixed with reference media
|
|
54
|
+
* content".
|
|
55
|
+
*/
|
|
56
|
+
export type BytePlusVideoContentRole =
|
|
57
|
+
| 'first_frame'
|
|
58
|
+
| 'last_frame'
|
|
59
|
+
| 'reference_image'
|
|
60
|
+
| 'reference_video'
|
|
61
|
+
| 'reference_audio'
|
|
62
|
+
|
|
63
|
+
/** Instruction text for the generation. */
|
|
64
|
+
export interface BytePlusVideoTextContent {
|
|
65
|
+
type: 'text'
|
|
66
|
+
text: string
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* An image input. A public URL is fetched by BytePlus server-side; a
|
|
71
|
+
* `data:` URI carries the bytes inline.
|
|
72
|
+
*/
|
|
73
|
+
export interface BytePlusVideoImageContent {
|
|
74
|
+
type: 'image_url'
|
|
75
|
+
image_url: { url: string }
|
|
76
|
+
/** Omitted for a bare first frame — the API defaults to `first_frame`. */
|
|
77
|
+
role?: BytePlusVideoContentRole
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** A video input. Reference-media mode requires `role: 'reference_video'`. */
|
|
81
|
+
export interface BytePlusVideoVideoContent {
|
|
82
|
+
type: 'video_url'
|
|
83
|
+
video_url: { url: string }
|
|
84
|
+
role?: BytePlusVideoContentRole
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* An audio input. Live-verified: audio can only accompany another reference
|
|
89
|
+
* input — "reference_audio cannot be the only reference input".
|
|
90
|
+
*/
|
|
91
|
+
export interface BytePlusVideoAudioContent {
|
|
92
|
+
type: 'audio_url'
|
|
93
|
+
audio_url: { url: string }
|
|
94
|
+
role?: BytePlusVideoContentRole
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* One entry of the `content[]` array.
|
|
99
|
+
*
|
|
100
|
+
* The create schema declares `maxItems: 5`, but the live API does not enforce
|
|
101
|
+
* it — 7 entries (6 reference images plus text) were accepted on
|
|
102
|
+
* `dreamina-seedance-2-0-260128`. The adapter therefore does not cap the array
|
|
103
|
+
* locally; a genuinely over-long request gets whatever Ark decides to say.
|
|
104
|
+
*/
|
|
105
|
+
export type BytePlusVideoContentPart =
|
|
106
|
+
| BytePlusVideoTextContent
|
|
107
|
+
| BytePlusVideoImageContent
|
|
108
|
+
| BytePlusVideoVideoContent
|
|
109
|
+
| BytePlusVideoAudioContent
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Request body for `POST /contents/generations/tasks`.
|
|
113
|
+
*
|
|
114
|
+
* Only `model` and `content` are required. Every other field is
|
|
115
|
+
* model-dependent — Ark rejects an inapplicable field outright ("the
|
|
116
|
+
* specified parameter `draft` is not supported for model … must be empty")
|
|
117
|
+
* rather than ignoring it, so the adapter only sends what the caller asked
|
|
118
|
+
* for. See `video-provider-options.ts` for the live-probed applicability
|
|
119
|
+
* matrix.
|
|
120
|
+
*/
|
|
121
|
+
export interface BytePlusVideoCreateRequest {
|
|
122
|
+
/** Seedance model id (or a preconfigured endpoint id). */
|
|
123
|
+
model: string
|
|
124
|
+
|
|
125
|
+
/** Prompt text plus any image / video / audio inputs, max 5 entries. */
|
|
126
|
+
content: Array<BytePlusVideoContentPart>
|
|
127
|
+
|
|
128
|
+
/** Output aspect ratio, e.g. `16:9`. `adaptive` follows the input frame. */
|
|
129
|
+
ratio?: string
|
|
130
|
+
|
|
131
|
+
/** Resolution tier, e.g. `720p`. Matched case-insensitively by the API. */
|
|
132
|
+
resolution?: string
|
|
133
|
+
|
|
134
|
+
/** Whole seconds of output. `-1` lets the model choose (Seedance 2.0 / 1.5). */
|
|
135
|
+
duration?: number
|
|
136
|
+
|
|
137
|
+
/** Frame count, an alternative to `duration` that allows fractional seconds. */
|
|
138
|
+
frames?: number
|
|
139
|
+
|
|
140
|
+
/** Randomness seed; integers in `[-1, 2^32-1]`, where `-1` means unseeded. */
|
|
141
|
+
seed?: number
|
|
142
|
+
|
|
143
|
+
/** Appends a "fix the camera" instruction to the prompt. Default `false`. */
|
|
144
|
+
camera_fixed?: boolean
|
|
145
|
+
|
|
146
|
+
/** Burn a watermark into the output. Default `false`. */
|
|
147
|
+
watermark?: boolean
|
|
148
|
+
|
|
149
|
+
/** Generate a synchronized audio track. Default `false`. */
|
|
150
|
+
generate_audio?: boolean
|
|
151
|
+
|
|
152
|
+
/** `default` (online) or `flex` (offline batch, half price). */
|
|
153
|
+
service_tier?: string
|
|
154
|
+
|
|
155
|
+
/** Also return the final frame as a PNG. Default `false`. */
|
|
156
|
+
return_last_frame?: boolean
|
|
157
|
+
|
|
158
|
+
/** Cheap low-fidelity preview render. Default `false`. */
|
|
159
|
+
draft?: boolean
|
|
160
|
+
|
|
161
|
+
/** Queue priority `[0, 9]`. */
|
|
162
|
+
priority?: number
|
|
163
|
+
|
|
164
|
+
/** Seconds from `created_at` after which the task is marked `expired`. */
|
|
165
|
+
execution_expires_after?: number
|
|
166
|
+
|
|
167
|
+
/** URL that receives a POST with the task payload on each status change. */
|
|
168
|
+
callback_url?: string
|
|
169
|
+
|
|
170
|
+
/** Opaque per-end-user identifier for abuse attribution, max 64 chars. */
|
|
171
|
+
safety_identifier?: string
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Response of `POST /contents/generations/tasks`.
|
|
176
|
+
*
|
|
177
|
+
* Live-verified: the body is just the task id (e.g.
|
|
178
|
+
* `cgt-batch-20260731174311-zmz5s`; the `-batch` infix appears when the task
|
|
179
|
+
* is routed to the `flex` offline queue).
|
|
180
|
+
*/
|
|
181
|
+
export interface BytePlusVideoCreateResponse {
|
|
182
|
+
id?: string
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Error detail attached to a terminal task.
|
|
187
|
+
*
|
|
188
|
+
* Codes are the dotted/PascalCase Ark strings — the create, get and list
|
|
189
|
+
* documents enumerate `InputTextSensitiveContentDetected`,
|
|
190
|
+
* `InputImageSensitiveContentDetected`, `OutputVideoSensitiveContentDetected`
|
|
191
|
+
* and `QuotaExceeded` under `x-error-code`. The set is open-ended, so this
|
|
192
|
+
* stays a plain `string`.
|
|
193
|
+
*/
|
|
194
|
+
export interface BytePlusVideoTaskError {
|
|
195
|
+
code?: string
|
|
196
|
+
message?: string
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Token usage for a finished task. Video generation bills output only, so
|
|
201
|
+
* `total_tokens` equals `completion_tokens` and there is no prompt count.
|
|
202
|
+
*
|
|
203
|
+
* The schema types both counts as `string` while the documented example
|
|
204
|
+
* response shows bare numbers, so both are accepted and coerced.
|
|
205
|
+
*/
|
|
206
|
+
export interface BytePlusVideoTaskUsage {
|
|
207
|
+
completion_tokens?: number | string
|
|
208
|
+
total_tokens?: number | string
|
|
209
|
+
/** Only present when a provider tool (web search) ran. */
|
|
210
|
+
tool_usage?: { web_search?: number }
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/** Output URLs of a succeeded task. Both links expire 24 hours after success. */
|
|
214
|
+
export interface BytePlusVideoTaskContent {
|
|
215
|
+
/** MP4 download URL. */
|
|
216
|
+
video_url?: string
|
|
217
|
+
/** Final frame as PNG; only when `return_last_frame` was set. */
|
|
218
|
+
last_frame_url?: string
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Response of `GET /contents/generations/tasks/{id}`.
|
|
223
|
+
*
|
|
224
|
+
* `content` appears once the task succeeds; `error` appears when it fails.
|
|
225
|
+
* Note `duration` comes back as a string here while the list endpoint types
|
|
226
|
+
* it as an integer, so both are accepted.
|
|
227
|
+
*/
|
|
228
|
+
export interface BytePlusVideoTask {
|
|
229
|
+
id?: string
|
|
230
|
+
/** `{model name}-{version}` actually used — not necessarily the id sent. */
|
|
231
|
+
model?: string
|
|
232
|
+
status?: BytePlusVideoTaskStatus
|
|
233
|
+
error?: BytePlusVideoTaskError
|
|
234
|
+
/** Unix seconds. Anchors the 7-day task-record retention. */
|
|
235
|
+
created_at?: number
|
|
236
|
+
/** Unix seconds of the last status change — for a succeeded task, when the
|
|
237
|
+
* output (and its 24-hour URL) was produced. */
|
|
238
|
+
updated_at?: number
|
|
239
|
+
content?: BytePlusVideoTaskContent
|
|
240
|
+
seed?: number
|
|
241
|
+
resolution?: string
|
|
242
|
+
ratio?: string
|
|
243
|
+
duration?: number | string
|
|
244
|
+
frames?: number
|
|
245
|
+
/** Frame rate. Lowercase and unseparated on the wire — not `frames_per_second`. */
|
|
246
|
+
framespersecond?: number
|
|
247
|
+
generate_audio?: boolean
|
|
248
|
+
service_tier?: string
|
|
249
|
+
draft?: boolean
|
|
250
|
+
draft_task_id?: string
|
|
251
|
+
execution_expires_after?: number
|
|
252
|
+
safety_identifier?: string
|
|
253
|
+
usage?: BytePlusVideoTaskUsage
|
|
254
|
+
|
|
255
|
+
// The two fields below came back on a live succeeded task
|
|
256
|
+
// (`seedance-1-0-pro-fast-251015`, 2026-07-31) but are absent from the
|
|
257
|
+
// harvested Get schema.
|
|
258
|
+
/** Queue priority the task ran at. */
|
|
259
|
+
priority?: number
|
|
260
|
+
/** Container of the generated video, e.g. `mp4`. */
|
|
261
|
+
output_format?: string
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* One entry of the list response.
|
|
266
|
+
*
|
|
267
|
+
* The list document declares the same fields as the get document (including
|
|
268
|
+
* `error` — despite BytePlus prose elsewhere calling the list-side field
|
|
269
|
+
* `failure_reason`, no such field exists in the harvested schema, so it is
|
|
270
|
+
* not typed here).
|
|
271
|
+
*/
|
|
272
|
+
export interface BytePlusVideoTaskListItem extends BytePlusVideoTask {}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Response of `GET /contents/generations/tasks`.
|
|
276
|
+
*
|
|
277
|
+
* Supported query parameters: `page_num` and `page_size` (both `[1, 500]`),
|
|
278
|
+
* `filter.status`, repeated `filter.task_ids`, and `filter.service_tier`.
|
|
279
|
+
*
|
|
280
|
+
* **`flex` tasks are missing from the default listing.** An unfiltered list
|
|
281
|
+
* returned `{total: 0, items: []}` both while a live `flex` task was running
|
|
282
|
+
* and immediately after it succeeded, so offline-tier work is invisible here
|
|
283
|
+
* unless `filter.service_tier=flex` is passed. Poll a known task id rather
|
|
284
|
+
* than relying on the listing to discover tasks.
|
|
285
|
+
*/
|
|
286
|
+
export interface BytePlusVideoTaskListResponse {
|
|
287
|
+
items?: Array<BytePlusVideoTaskListItem>
|
|
288
|
+
total?: number
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// `DELETE /contents/generations/tasks/{id}` cancels a `queued` task and
|
|
292
|
+
// deletes anything already terminal; its documented success body is an empty
|
|
293
|
+
// object, so no response interface is declared for it.
|