@openclaw/byteplus-provider 2026.10.10 → 2026.11.5-beta.1

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/README.md CHANGED
@@ -15,3 +15,7 @@ Set `BYTEPLUS_API_KEY`, then select a `byteplus/*` or `byteplus-plan/*` model.
15
15
  See <https://docs.openclaw.ai/concepts/model-providers#byteplus-international>
16
16
  for model setup and <https://docs.openclaw.ai/tools/video-generation> for
17
17
  Seedance video generation.
18
+
19
+ Video task submission and polling use headers and proxy settings from
20
+ `models.providers.byteplus.request`. Generated video downloads do not inherit
21
+ those task credentials or transport overrides.
@@ -1 +1 @@
1
- {"version":3,"entries":[{"output":"api.js","source":"extensions/byteplus/api.ts"},{"output":"index.js","source":"extensions/byteplus/index.ts"},{"output":"models.js","source":"extensions/byteplus/models.ts"},{"output":"provider-discovery.js","source":"extensions/byteplus/provider-discovery.ts"},{"output":"video-generation-provider.js","source":"extensions/byteplus/video-generation-provider.ts"}],"chunks":[{"output":".setup/models-C1qBj9Lo.mjs","sha256":"225965e64ed3816174b3b6c8004cdb106e64632f323b67867525212be70d20d9","facadeSource":null,"sources":["extensions/byteplus/models.ts","extensions/byteplus/openclaw.plugin.json"]},{"output":"api.js","sha256":"94b013544bf766eea72a32cedcc387bfe81e8d7c6584abf2ff0d6cfe5ec97c1a","facadeSource":"extensions/byteplus/api.ts","sources":[]},{"output":"index.js","sha256":"c94b1cc10ed2164ae9d78aa6e342182717f14c02e778908943edb9e06ea96ddc","facadeSource":"extensions/byteplus/index.ts","sources":["extensions/byteplus/index.ts"]},{"output":"models.js","sha256":"30ca9349bf50a0dbe6fae836d8f30ba2f838e77e908d7f975c86eaed7e491e3b","facadeSource":"extensions/byteplus/models.ts","sources":[]},{"output":"provider-discovery.js","sha256":"9a9a33ce0ea1d8b9ff87cccde29b2177d7149a0140fd002703afde9402969570","facadeSource":"extensions/byteplus/provider-discovery.ts","sources":["extensions/byteplus/provider-discovery.ts"]},{"output":"video-generation-provider.js","sha256":"f617dd59700e37b90cd2fb5fb961b489fdf3c9a9c437b57a57d2e3f1120e3f7f","facadeSource":"extensions/byteplus/video-generation-provider.ts","sources":["extensions/byteplus/video-generation-provider.ts"]}],"unrenderedSources":["extensions/byteplus/api.ts"]}
1
+ {"version":3,"entries":[{"output":"api.js","source":"extensions/byteplus/api.ts"},{"output":"index.js","source":"extensions/byteplus/index.ts"},{"output":"models.js","source":"extensions/byteplus/models.ts"},{"output":"provider-discovery.js","source":"extensions/byteplus/provider-discovery.ts"},{"output":"video-generation-provider.js","source":"extensions/byteplus/video-generation-provider.ts"}],"chunks":[{"output":".setup/models-C1qBj9Lo.mjs","sha256":"225965e64ed3816174b3b6c8004cdb106e64632f323b67867525212be70d20d9","facadeSource":null,"sources":["extensions/byteplus/models.ts","extensions/byteplus/openclaw.plugin.json"]},{"output":"api.js","sha256":"94b013544bf766eea72a32cedcc387bfe81e8d7c6584abf2ff0d6cfe5ec97c1a","facadeSource":"extensions/byteplus/api.ts","sources":[]},{"output":"index.js","sha256":"c94b1cc10ed2164ae9d78aa6e342182717f14c02e778908943edb9e06ea96ddc","facadeSource":"extensions/byteplus/index.ts","sources":["extensions/byteplus/index.ts"]},{"output":"models.js","sha256":"30ca9349bf50a0dbe6fae836d8f30ba2f838e77e908d7f975c86eaed7e491e3b","facadeSource":"extensions/byteplus/models.ts","sources":[]},{"output":"provider-discovery.js","sha256":"9a9a33ce0ea1d8b9ff87cccde29b2177d7149a0140fd002703afde9402969570","facadeSource":"extensions/byteplus/provider-discovery.ts","sources":["extensions/byteplus/provider-discovery.ts"]},{"output":"video-generation-provider.js","sha256":"1d0a9e0425aa15202de58d1e1ef44b7059e6d877cd7929c2ca0c1e5e0eccd460","facadeSource":"extensions/byteplus/video-generation-provider.ts","sources":["extensions/byteplus/video-generation-provider.ts"]}],"unrenderedSources":["extensions/byteplus/api.ts"]}
@@ -1,9 +1,8 @@
1
1
  import { t as BYTEPLUS_BASE_URL } from "./.setup/models-C1qBj9Lo.mjs";
2
- import { toImageDataUrl } from "openclaw/plugin-sdk/image-generation";
2
+ import { resolveImageSourceUrl } from "openclaw/plugin-sdk/image-generation";
3
3
  import { downloadGeneratedVideoAsset, resolveGeneratedMediaMaxBytes } from "openclaw/plugin-sdk/media-generation-runtime";
4
4
  import { isProviderApiKeyConfiguredAsync } from "openclaw/plugin-sdk/provider-auth";
5
- import { resolveApiKeyForProvider } from "openclaw/plugin-sdk/provider-auth-runtime";
6
- import { assertOkOrThrowHttpError, createProviderOperationDeadline, createProviderOperationTimeoutResolver, pollProviderOperationJson, postJsonRequest, readProviderJsonObjectResponse, resolveProviderHttpRequestConfig, resolveProviderOperationTimeoutMs } from "openclaw/plugin-sdk/provider-http";
5
+ import { createProviderOperationDeadline, createProviderOperationTimeoutResolver, pollProviderOperationJson, postJsonResponse, resolveProviderApiKeyHttpRequestConfig, resolveProviderOperationTimeoutMs, sanitizeConfiguredModelProviderRequest } from "openclaw/plugin-sdk/provider-http";
7
6
  import { asSafeIntegerInRange, isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
8
7
  // extensions/byteplus/video-generation-provider.ts
9
8
  const DEFAULT_BYTEPLUS_VIDEO_MODEL = "seedance-1-0-pro-250528";
@@ -28,32 +27,6 @@ function readBytePlusTaskStatus(payload) {
28
27
  function readBytePlusErrorMessage(error) {
29
28
  return isRecord(error) ? normalizeOptionalString(error.message) : void 0;
30
29
  }
31
- function readBytePlusVideoUrl(payload) {
32
- const content = payload.content;
33
- if (content !== void 0 && !isRecord(content)) throw new Error("BytePlus video generation completed with malformed content");
34
- const videoUrl = normalizeOptionalString(content?.video_url);
35
- if (!videoUrl) throw new Error("BytePlus video generation completed without a video URL");
36
- return videoUrl;
37
- }
38
- function resolveBytePlusImageUrl(req) {
39
- const input = req.inputImages?.[0];
40
- if (!input) return;
41
- const inputUrl = normalizeOptionalString(input.url);
42
- if (inputUrl) return inputUrl;
43
- if (!input.buffer) throw new Error("BytePlus reference image is missing image data.");
44
- return toImageDataUrl({
45
- ...input,
46
- buffer: input.buffer,
47
- defaultMimeType: "image/png"
48
- });
49
- }
50
- function resolveBytePlusDurationSeconds(value) {
51
- if (typeof value !== "number" || !Number.isFinite(value)) return;
52
- return asSafeIntegerInRange(Math.round(value), {
53
- min: BYTEPLUS_MIN_DURATION_SECONDS,
54
- max: BYTEPLUS_MAX_DURATION_SECONDS
55
- });
56
- }
57
30
  function buildBytePlusVideoGenerationProvider() {
58
31
  return {
59
32
  id: "byteplus",
@@ -92,36 +65,27 @@ function buildBytePlusVideoGenerationProvider() {
92
65
  },
93
66
  async generateVideo(req) {
94
67
  if ((req.inputVideos?.length ?? 0) > 0) throw new Error("BytePlus video generation does not support video reference inputs.");
95
- const auth = await resolveApiKeyForProvider({
68
+ const fetchFn = fetch;
69
+ const { baseUrl, allowPrivateNetwork, headers, dispatcherPolicy } = await resolveProviderApiKeyHttpRequestConfig({
70
+ req,
71
+ missingApiKeyMessage: "BytePlus API key missing",
72
+ baseUrl: req.cfg?.models?.providers?.byteplus?.baseUrl,
73
+ defaultBaseUrl: BYTEPLUS_BASE_URL,
74
+ request: sanitizeConfiguredModelProviderRequest(req.cfg?.models?.providers?.byteplus?.request),
75
+ allowPrivateNetwork: false,
96
76
  provider: "byteplus",
97
- cfg: req.cfg,
98
- agentDir: req.agentDir,
99
- store: req.authStore
77
+ capability: "video"
100
78
  });
101
- if (!auth.apiKey) throw new Error("BytePlus API key missing");
102
- const fetchFn = fetch;
103
79
  const deadline = createProviderOperationDeadline({
104
80
  timeoutMs: req.timeoutMs,
105
81
  label: "BytePlus video generation"
106
82
  });
107
- const { baseUrl, allowPrivateNetwork, headers, dispatcherPolicy } = resolveProviderHttpRequestConfig({
108
- baseUrl: normalizeOptionalString(req.cfg?.models?.providers?.byteplus?.baseUrl) ?? BYTEPLUS_BASE_URL,
109
- defaultBaseUrl: BYTEPLUS_BASE_URL,
110
- allowPrivateNetwork: false,
111
- defaultHeaders: {
112
- Authorization: `Bearer ${auth.apiKey}`,
113
- "Content-Type": "application/json"
114
- },
115
- provider: "byteplus",
116
- capability: "video",
117
- transport: "http"
118
- });
119
83
  const resolvedModel = normalizeOptionalString(req.model) || DEFAULT_BYTEPLUS_VIDEO_MODEL;
120
84
  const content = [{
121
85
  type: "text",
122
86
  text: req.prompt
123
87
  }];
124
- const imageUrl = resolveBytePlusImageUrl(req);
88
+ const imageUrl = resolveImageSourceUrl(req.inputImages?.[0], "BytePlus reference image is missing image data.");
125
89
  if (imageUrl) content.push({
126
90
  type: "image_url",
127
91
  image_url: { url: imageUrl },
@@ -135,10 +99,16 @@ function buildBytePlusVideoGenerationProvider() {
135
99
  if (aspectRatio) body.ratio = aspectRatio;
136
100
  const resolution = normalizeOptionalString(req.resolution)?.toLowerCase();
137
101
  if (resolution) body.resolution = resolution;
138
- const duration = resolveBytePlusDurationSeconds(req.durationSeconds);
139
- if (duration !== void 0) body.duration = duration;
140
- if (typeof req.audio === "boolean") body.generate_audio = req.audio;
141
- if (typeof req.watermark === "boolean") body.watermark = req.watermark;
102
+ const requestedDuration = req.durationSeconds;
103
+ if (typeof requestedDuration === "number" && Number.isFinite(requestedDuration)) {
104
+ const duration = asSafeIntegerInRange(Math.round(requestedDuration), {
105
+ min: BYTEPLUS_MIN_DURATION_SECONDS,
106
+ max: BYTEPLUS_MAX_DURATION_SECONDS
107
+ });
108
+ if (duration !== void 0) body.duration = duration;
109
+ }
110
+ if (req.audio !== void 0) body.generate_audio = req.audio;
111
+ if (req.watermark !== void 0) body.watermark = req.watermark;
142
112
  const opts = req.providerOptions ?? {};
143
113
  const seed = asSafeIntegerInRange(opts.seed, {
144
114
  min: -1,
@@ -149,7 +119,7 @@ function buildBytePlusVideoGenerationProvider() {
149
119
  if (seed != null) body.seed = seed;
150
120
  if (draft && !body.resolution) body.resolution = "480p";
151
121
  if (cameraFixed != null) body.camera_fixed = cameraFixed;
152
- const { response, release } = await postJsonRequest({
122
+ const submitted = await postJsonResponse({
153
123
  url: `${baseUrl}/contents/generations/tasks`,
154
124
  headers,
155
125
  body,
@@ -159,67 +129,69 @@ function buildBytePlusVideoGenerationProvider() {
159
129
  }),
160
130
  fetchFn,
161
131
  allowPrivateNetwork,
162
- dispatcherPolicy
132
+ dispatcherPolicy,
133
+ errorLabel: "BytePlus video generation failed",
134
+ objectResponse: true
135
+ });
136
+ const taskId = normalizeOptionalString(submitted.id);
137
+ if (!taskId) throw new Error("BytePlus video generation response missing task id");
138
+ const completed = await pollProviderOperationJson({
139
+ url: `${baseUrl}/contents/generations/tasks/${taskId}`,
140
+ headers,
141
+ deadline: createProviderOperationDeadline({
142
+ timeoutMs: resolveProviderOperationTimeoutMs({
143
+ deadline,
144
+ defaultTimeoutMs: DEFAULT_TIMEOUT_MS
145
+ }),
146
+ label: `BytePlus video generation task ${taskId}`
147
+ }),
148
+ defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
149
+ fetchFn,
150
+ maxAttempts: MAX_POLL_ATTEMPTS,
151
+ ssrfPolicy: { allowPrivateNetwork },
152
+ dispatcherPolicy,
153
+ pollIntervalMs: POLL_INTERVAL_MS,
154
+ requestFailedMessage: "BytePlus video status request failed",
155
+ timeoutMessage: `BytePlus video generation task ${taskId} did not finish in time`,
156
+ isComplete: (payload) => readBytePlusTaskStatus(payload) === "succeeded",
157
+ getFailureMessage: (payload) => {
158
+ const status = readBytePlusTaskStatus(payload);
159
+ return status === "failed" || status === "cancelled" ? readBytePlusErrorMessage(payload.error) || "BytePlus video generation failed" : void 0;
160
+ }
163
161
  });
164
- try {
165
- await assertOkOrThrowHttpError(response, "BytePlus video generation failed");
166
- const submitted = await readProviderJsonObjectResponse(response, "BytePlus video generation failed");
167
- const taskId = normalizeOptionalString(submitted.id);
168
- if (!taskId) throw new Error("BytePlus video generation response missing task id");
169
- const completed = await pollProviderOperationJson({
170
- url: `${baseUrl}/contents/generations/tasks/${taskId}`,
171
- headers,
172
- deadline: createProviderOperationDeadline({
173
- timeoutMs: resolveProviderOperationTimeoutMs({
174
- deadline,
175
- defaultTimeoutMs: DEFAULT_TIMEOUT_MS
176
- }),
177
- label: `BytePlus video generation task ${taskId}`
162
+ const completedContent = completed.content;
163
+ if (completedContent !== void 0 && !isRecord(completedContent)) throw new Error("BytePlus video generation completed with malformed content");
164
+ const videoUrl = normalizeOptionalString(completedContent?.video_url);
165
+ if (!videoUrl) throw new Error("BytePlus video generation completed without a video URL");
166
+ return {
167
+ videos: [await downloadGeneratedVideoAsset({
168
+ url: videoUrl,
169
+ timeoutMs: createProviderOperationTimeoutResolver({
170
+ deadline,
171
+ defaultTimeoutMs: DEFAULT_TIMEOUT_MS
178
172
  }),
179
173
  defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
180
174
  fetchFn,
181
- maxAttempts: MAX_POLL_ATTEMPTS,
182
- pollIntervalMs: POLL_INTERVAL_MS,
183
- requestFailedMessage: "BytePlus video status request failed",
184
- timeoutMessage: `BytePlus video generation task ${taskId} did not finish in time`,
185
- isComplete: (payload) => readBytePlusTaskStatus(payload) === "succeeded",
186
- getFailureMessage: (payload) => {
187
- const status = readBytePlusTaskStatus(payload);
188
- return status === "failed" || status === "cancelled" ? readBytePlusErrorMessage(payload.error) || "BytePlus video generation failed" : void 0;
189
- }
190
- });
191
- const videoUrl = readBytePlusVideoUrl(completed);
192
- return {
193
- videos: [await downloadGeneratedVideoAsset({
194
- url: videoUrl,
195
- timeoutMs: createProviderOperationTimeoutResolver({
196
- deadline,
197
- defaultTimeoutMs: DEFAULT_TIMEOUT_MS
198
- }),
199
- defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
200
- fetchFn,
201
- provider: "byteplus",
202
- label: "BytePlus generated video download",
203
- requestFailedMessage: "BytePlus generated video download failed",
204
- maxBytes: resolveGeneratedMediaMaxBytes(req.cfg, "video"),
205
- validateBinaryResponse: true
206
- })],
207
- model: normalizeOptionalString(completed.model) ?? resolvedModel,
208
- metadata: {
209
- taskId,
210
- status: normalizeOptionalString(completed.status),
211
- videoUrl,
212
- ratio: normalizeOptionalString(completed.ratio),
213
- resolution: normalizeOptionalString(completed.resolution),
214
- duration: asSafeIntegerInRange(completed.duration, {
215
- min: BYTEPLUS_MIN_DURATION_SECONDS,
216
- max: BYTEPLUS_MAX_DURATION_SECONDS
217
- })
218
- }
219
- };
220
- } finally {
221
- await release();
222
- }
175
+ provider: "byteplus",
176
+ label: "BytePlus generated video download",
177
+ requestFailedMessage: "BytePlus generated video download failed",
178
+ maxBytes: resolveGeneratedMediaMaxBytes(req.cfg, "video"),
179
+ validateBinaryResponse: true,
180
+ dispatcherPolicy
181
+ })],
182
+ model: normalizeOptionalString(completed.model) ?? resolvedModel,
183
+ metadata: {
184
+ taskId,
185
+ status: normalizeOptionalString(completed.status),
186
+ videoUrl,
187
+ ratio: normalizeOptionalString(completed.ratio),
188
+ resolution: normalizeOptionalString(completed.resolution),
189
+ duration: asSafeIntegerInRange(completed.duration, {
190
+ min: BYTEPLUS_MIN_DURATION_SECONDS,
191
+ max: BYTEPLUS_MAX_DURATION_SECONDS
192
+ })
193
+ }
194
+ };
223
195
  }
224
196
  };
225
197
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/byteplus-provider",
3
- "version": "2026.10.10",
3
+ "version": "2026.11.5-beta.1",
4
4
  "description": "OpenClaw BytePlus provider plugin.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -18,10 +18,10 @@
18
18
  "minHostVersion": ">=2026.7.2"
19
19
  },
20
20
  "compat": {
21
- "pluginApi": ">=2026.10.10"
21
+ "pluginApi": ">=2026.11.5-beta.1"
22
22
  },
23
23
  "build": {
24
- "openclawVersion": "2026.10.10",
24
+ "openclawVersion": "2026.11.5-beta.1",
25
25
  "bundledDist": false
26
26
  },
27
27
  "release": {
@@ -40,7 +40,7 @@
40
40
  "assets/activity.svg"
41
41
  ],
42
42
  "peerDependencies": {
43
- "openclaw": ">=2026.10.10"
43
+ "openclaw": ">=2026.11.5-beta.1"
44
44
  },
45
45
  "peerDependenciesMeta": {
46
46
  "openclaw": {