@openclaw/pixverse-provider 2026.9.7 → 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 +18 -27
- package/dist/video-generation-provider.js +62 -98
- package/package.json +4 -4
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
|
|
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 =
|
|
13
|
-
|
|
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
|
|
47
|
-
|
|
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,
|
|
82
|
-
notes: [
|
|
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",
|
|
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
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
88
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
308
|
-
const
|
|
309
|
-
|
|
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
|
-
|
|
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: [
|
|
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.
|
|
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.
|
|
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.
|
|
29
|
+
"pluginApi": ">=2026.10.1-beta.1"
|
|
30
30
|
},
|
|
31
31
|
"build": {
|
|
32
|
-
"openclawVersion": "2026.
|
|
32
|
+
"openclawVersion": "2026.10.1-beta.1",
|
|
33
33
|
"bundledDist": false
|
|
34
34
|
},
|
|
35
35
|
"release": {
|