@openclaw/pixverse-provider 2026.9.8 → 2026.10.1-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/dist/onboard.js CHANGED
@@ -3,14 +3,11 @@ import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runti
3
3
  import { applyAuthProfileConfig, buildApiKeyCredential, captureProviderApiKey, normalizeOptionalSecretInput, persistProviderApiKey } from "openclaw/plugin-sdk/provider-auth-api-key";
4
4
  //#region extensions/pixverse/onboard.ts
5
5
  const PROFILE_ID = `${PIXVERSE_PROVIDER_ID}:default`;
6
- function pixVerseRegionNote(region) {
7
- return `PixVerse endpoint: ${region === "cn" ? "CN" : "International"} (${PIXVERSE_BASE_URL_BY_REGION[region]})`;
8
- }
9
- function applyPixVerseProviderConfig(cfg, region, options) {
6
+ function applyPixVerseConfig(cfg, region, resetBaseUrl) {
10
7
  const existingProvider = cfg.models?.providers?.["pixverse"] ?? {};
11
8
  const selectedBaseUrl = PIXVERSE_BASE_URL_BY_REGION[region];
12
- const baseUrl = options?.resetBaseUrl ? selectedBaseUrl : normalizeOptionalString(existingProvider.baseUrl) ?? selectedBaseUrl;
13
- return {
9
+ const baseUrl = resetBaseUrl ? selectedBaseUrl : normalizeOptionalString(existingProvider.baseUrl) ?? selectedBaseUrl;
10
+ const next = {
14
11
  ...cfg,
15
12
  models: {
16
13
  ...cfg.models,
@@ -25,9 +22,6 @@ function applyPixVerseProviderConfig(cfg, region, options) {
25
22
  }
26
23
  }
27
24
  };
28
- }
29
- function applyPixVerseConfig(cfg, region, options) {
30
- const next = applyPixVerseProviderConfig(cfg, region, options);
31
25
  if (next.agents?.defaults?.mediaModels?.video) return next;
32
26
  return {
33
27
  ...next,
@@ -43,8 +37,18 @@ function applyPixVerseConfig(cfg, region, options) {
43
37
  }
44
38
  };
45
39
  }
46
- async function promptForPixVerseRegion(ctx) {
47
- return await ctx.prompter.select({
40
+ async function runPixVerseApiKeyAuth(ctx) {
41
+ const { input, mode } = await captureProviderApiKey(ctx, {
42
+ token: normalizeOptionalSecretInput(ctx.opts?.pixverseApiKey) ?? normalizeOptionalSecretInput(ctx.opts?.token),
43
+ tokenProvider: normalizeOptionalSecretInput(ctx.opts?.pixverseApiKey) ? PIXVERSE_PROVIDER_ID : normalizeOptionalSecretInput(ctx.opts?.tokenProvider),
44
+ env: ctx.env,
45
+ expectedProviders: [PIXVERSE_PROVIDER_ID],
46
+ provider: PIXVERSE_PROVIDER_ID,
47
+ envLabel: "PIXVERSE_API_KEY",
48
+ promptMessage: "Enter PixVerse API key",
49
+ missingInputMessage: "Missing PixVerse API key."
50
+ });
51
+ const region = await ctx.prompter.select({
48
52
  message: "Select PixVerse API region",
49
53
  initialValue: DEFAULT_PIXVERSE_REGION,
50
54
  options: [{
@@ -57,19 +61,6 @@ async function promptForPixVerseRegion(ctx) {
57
61
  hint: PIXVERSE_BASE_URL_BY_REGION.cn
58
62
  }]
59
63
  });
60
- }
61
- async function runPixVerseApiKeyAuth(ctx) {
62
- const { input, mode } = await captureProviderApiKey(ctx, {
63
- token: normalizeOptionalSecretInput(ctx.opts?.pixverseApiKey) ?? normalizeOptionalSecretInput(ctx.opts?.token),
64
- tokenProvider: normalizeOptionalSecretInput(ctx.opts?.pixverseApiKey) ? PIXVERSE_PROVIDER_ID : normalizeOptionalSecretInput(ctx.opts?.tokenProvider),
65
- env: ctx.env,
66
- expectedProviders: [PIXVERSE_PROVIDER_ID],
67
- provider: PIXVERSE_PROVIDER_ID,
68
- envLabel: "PIXVERSE_API_KEY",
69
- promptMessage: "Enter PixVerse API key",
70
- missingInputMessage: "Missing PixVerse API key."
71
- });
72
- const region = await promptForPixVerseRegion(ctx);
73
64
  return {
74
65
  profiles: [{
75
66
  profileId: PROFILE_ID,
@@ -78,8 +69,8 @@ async function runPixVerseApiKeyAuth(ctx) {
78
69
  config: ctx.config
79
70
  } : void 0)
80
71
  }],
81
- configPatch: applyPixVerseConfig(ctx.config, region, { resetBaseUrl: true }),
82
- notes: [pixVerseRegionNote(region)]
72
+ configPatch: applyPixVerseConfig(ctx.config, region, true),
73
+ notes: [`PixVerse endpoint: ${region === "cn" ? "CN" : "International"} (${PIXVERSE_BASE_URL_BY_REGION[region]})`]
83
74
  };
84
75
  }
85
76
  async function runPixVerseApiKeyAuthNonInteractive(ctx) {
@@ -100,7 +91,7 @@ async function runPixVerseApiKeyAuthNonInteractive(ctx) {
100
91
  mode: "api_key"
101
92
  });
102
93
  const explicitRegion = normalizePixVerseRegion(ctx.opts.pixverseRegion);
103
- return applyPixVerseConfig(next, explicitRegion ?? "international", { resetBaseUrl: explicitRegion !== void 0 });
94
+ return applyPixVerseConfig(next, explicitRegion ?? "international", explicitRegion !== void 0);
104
95
  }
105
96
  function buildPixVerseApiKeyAuthMethod() {
106
97
  return {
@@ -82,20 +82,13 @@ function readPixVerseSuccess(payload, label) {
82
82
  async function readPixVerseJson(response, label) {
83
83
  return readPixVerseSuccess(await readProviderJsonResponse(response, label), label);
84
84
  }
85
- function readPixVerseVideoId(payload) {
86
- const videoId = asSafeIntegerInRange(payload.video_id, { min: 0 });
87
- if (videoId == null) throw new Error("PixVerse video generation response missing video_id");
88
- return videoId;
89
- }
90
- function readPixVerseImageId(payload) {
91
- const imageId = asSafeIntegerInRange(payload.img_id, { min: 0 });
92
- if (imageId == null) throw new Error("PixVerse image upload response missing img_id");
93
- return imageId;
85
+ function readPixVerseInteger(value, label) {
86
+ const integer = asSafeIntegerInRange(value, { min: 0 });
87
+ if (integer === void 0) throw new Error(label);
88
+ return integer;
94
89
  }
95
90
  function readPixVerseStatus(payload) {
96
- const status = asSafeIntegerInRange(payload.status, { min: 0 });
97
- if (status == null) throw new Error("PixVerse video status response missing status");
98
- return status;
91
+ return readPixVerseInteger(payload.status, "PixVerse video status response missing status");
99
92
  }
100
93
  function buildUploadImageForm(asset) {
101
94
  const form = new FormData();
@@ -143,35 +136,35 @@ function readPixVerseFailureMessage(payload) {
143
136
  default: return;
144
137
  }
145
138
  }
146
- async function pollPixVerseVideo(params) {
147
- const readResult = (payload) => readPixVerseSuccess(payload, "PixVerse video status request failed");
148
- return readResult(await pollProviderOperationJson({
149
- url: `${params.baseUrl}/video/result/${params.videoId}`,
150
- headers: () => buildPixVerseHeaders(params.headers),
151
- deadline: params.deadline,
152
- defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
153
- fetchFn: params.fetchFn,
154
- maxAttempts: MAX_POLL_ATTEMPTS,
155
- pollIntervalMs: POLL_INTERVAL_MS,
156
- requestFailedMessage: "PixVerse video status request failed",
157
- timeoutMessage: `PixVerse video generation task ${params.videoId} did not finish in time`,
158
- isComplete: (candidate) => readPixVerseStatus(readResult(candidate)) === 1,
159
- getFailureMessage: (candidate) => readPixVerseFailureMessage(readResult(candidate)),
160
- allowPrivateNetwork: params.allowPrivateNetwork,
161
- dispatcherPolicy: params.dispatcherPolicy
162
- }));
163
- }
164
- function extractPixVerseVideo(payload) {
165
- const url = normalizeOptionalString(payload.url);
166
- if (!url) throw new Error("PixVerse video generation completed without output URL");
139
+ function buildPixVerseModeCapabilities(imageToVideo = false) {
167
140
  return {
168
- url,
169
- mimeType: "video/mp4",
170
- fileName: "video-1.mp4",
171
- metadata: {
172
- sourceUrl: url,
173
- outputWidth: asFiniteNumber(payload.outputWidth),
174
- outputHeight: asFiniteNumber(payload.outputHeight)
141
+ maxVideos: 1,
142
+ ...imageToVideo ? { maxInputImages: 1 } : {},
143
+ maxDurationSeconds: MAX_DURATION_SECONDS,
144
+ supportedDurationSeconds: Array.from({ length: MAX_DURATION_SECONDS }, (_, index) => index + 1),
145
+ ...!imageToVideo ? { aspectRatios: [...PIXVERSE_TEXT_ASPECT_RATIOS] } : {},
146
+ resolutions: [
147
+ "360P",
148
+ "540P",
149
+ "720P",
150
+ "1080P"
151
+ ],
152
+ ...!imageToVideo ? { supportsAspectRatio: true } : {},
153
+ supportsResolution: true,
154
+ supportsAudio: true,
155
+ providerOptions: {
156
+ seed: "number",
157
+ negative_prompt: "string",
158
+ negativePrompt: "string",
159
+ quality: "string",
160
+ ...imageToVideo ? {
161
+ motion_mode: "string",
162
+ motionMode: "string"
163
+ } : {},
164
+ camera_movement: "string",
165
+ cameraMovement: "string",
166
+ template_id: "number",
167
+ templateId: "number"
175
168
  }
176
169
  };
177
170
  }
@@ -187,57 +180,10 @@ function buildPixVerseVideoGenerationProvider() {
187
180
  ...ctx
188
181
  }),
189
182
  capabilities: {
190
- generate: {
191
- maxVideos: 1,
192
- maxDurationSeconds: MAX_DURATION_SECONDS,
193
- supportedDurationSeconds: Array.from({ length: MAX_DURATION_SECONDS }, (_, index) => index + 1),
194
- aspectRatios: [...PIXVERSE_TEXT_ASPECT_RATIOS],
195
- resolutions: [
196
- "360P",
197
- "540P",
198
- "720P",
199
- "1080P"
200
- ],
201
- supportsAspectRatio: true,
202
- supportsResolution: true,
203
- supportsAudio: true,
204
- providerOptions: {
205
- seed: "number",
206
- negative_prompt: "string",
207
- negativePrompt: "string",
208
- quality: "string",
209
- camera_movement: "string",
210
- cameraMovement: "string",
211
- template_id: "number",
212
- templateId: "number"
213
- }
214
- },
183
+ generate: buildPixVerseModeCapabilities(),
215
184
  imageToVideo: {
216
185
  enabled: true,
217
- maxVideos: 1,
218
- maxInputImages: 1,
219
- maxDurationSeconds: MAX_DURATION_SECONDS,
220
- supportedDurationSeconds: Array.from({ length: MAX_DURATION_SECONDS }, (_, index) => index + 1),
221
- resolutions: [
222
- "360P",
223
- "540P",
224
- "720P",
225
- "1080P"
226
- ],
227
- supportsResolution: true,
228
- supportsAudio: true,
229
- providerOptions: {
230
- seed: "number",
231
- negative_prompt: "string",
232
- negativePrompt: "string",
233
- quality: "string",
234
- motion_mode: "string",
235
- motionMode: "string",
236
- camera_movement: "string",
237
- cameraMovement: "string",
238
- template_id: "number",
239
- templateId: "number"
240
- }
186
+ ...buildPixVerseModeCapabilities(true)
241
187
  },
242
188
  videoToVideo: { enabled: false }
243
189
  },
@@ -284,7 +230,7 @@ function buildPixVerseVideoGenerationProvider() {
284
230
  });
285
231
  try {
286
232
  await assertOkOrThrowHttpError(upload.response, "PixVerse image upload failed");
287
- imageId = readPixVerseImageId(await readPixVerseJson(upload.response, "PixVerse image upload failed"));
233
+ imageId = readPixVerseInteger((await readPixVerseJson(upload.response, "PixVerse image upload failed")).img_id, "PixVerse image upload response missing img_id");
288
234
  } finally {
289
235
  await upload.release();
290
236
  }
@@ -304,18 +250,36 @@ function buildPixVerseVideoGenerationProvider() {
304
250
  });
305
251
  try {
306
252
  await assertOkOrThrowHttpError(create.response, "PixVerse video generation failed");
307
- const videoId = readPixVerseVideoId(await readPixVerseJson(create.response, "PixVerse video generation failed"));
308
- const completed = await pollPixVerseVideo({
309
- videoId,
310
- baseUrl,
253
+ const videoId = readPixVerseInteger((await readPixVerseJson(create.response, "PixVerse video generation failed")).video_id, "PixVerse video generation response missing video_id");
254
+ const readResult = (payload) => readPixVerseSuccess(payload, "PixVerse video status request failed");
255
+ const completed = readResult(await pollProviderOperationJson({
256
+ url: `${baseUrl}/video/result/${videoId}`,
257
+ headers: () => buildPixVerseHeaders(headers),
311
258
  deadline,
259
+ defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
312
260
  fetchFn,
261
+ maxAttempts: MAX_POLL_ATTEMPTS,
262
+ pollIntervalMs: POLL_INTERVAL_MS,
263
+ requestFailedMessage: "PixVerse video status request failed",
264
+ timeoutMessage: `PixVerse video generation task ${videoId} did not finish in time`,
265
+ isComplete: (candidate) => readPixVerseStatus(readResult(candidate)) === 1,
266
+ getFailureMessage: (candidate) => readPixVerseFailureMessage(readResult(candidate)),
313
267
  allowPrivateNetwork,
314
- dispatcherPolicy,
315
- headers
316
- });
268
+ dispatcherPolicy
269
+ }));
270
+ const url = normalizeOptionalString(completed.url);
271
+ if (!url) throw new Error("PixVerse video generation completed without output URL");
317
272
  return {
318
- videos: [extractPixVerseVideo(completed)],
273
+ videos: [{
274
+ url,
275
+ mimeType: "video/mp4",
276
+ fileName: "video-1.mp4",
277
+ metadata: {
278
+ sourceUrl: url,
279
+ outputWidth: asFiniteNumber(completed.outputWidth),
280
+ outputHeight: asFiniteNumber(completed.outputHeight)
281
+ }
282
+ }],
319
283
  model,
320
284
  metadata: {
321
285
  endpoint,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/pixverse-provider",
3
- "version": "2026.9.8",
3
+ "version": "2026.10.1-beta.1",
4
4
  "description": "OpenClaw PixVerse video generation provider plugin.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "type": "module",
10
10
  "peerDependencies": {
11
- "openclaw": ">=2026.9.8"
11
+ "openclaw": ">=2026.10.1-beta.1"
12
12
  },
13
13
  "peerDependenciesMeta": {
14
14
  "openclaw": {
@@ -26,10 +26,10 @@
26
26
  "minHostVersion": ">=2026.5.26"
27
27
  },
28
28
  "compat": {
29
- "pluginApi": ">=2026.9.8"
29
+ "pluginApi": ">=2026.10.1-beta.1"
30
30
  },
31
31
  "build": {
32
- "openclawVersion": "2026.9.8",
32
+ "openclawVersion": "2026.10.1-beta.1",
33
33
  "bundledDist": false
34
34
  },
35
35
  "release": {