@openclaw/pixverse-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/dist/.source-module-urls/d6f705ce2a531f2fd1e242ce7946d2c08d9b810dbee0c50a3bf7f36bb88fd40c.json +1 -0
- package/dist/index.js +97 -3
- package/dist/video-generation-provider.js +93 -122
- package/package.json +4 -4
- package/dist/.source-module-urls/2e753a0a50ebcfebf12933226a56f06be1f5d542653f874ac0dc909a7fd394c1.json +0 -1
- package/dist/onboard.js +0 -115
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"entries":[{"output":"constants.js","source":"extensions/pixverse/constants.ts"},{"output":"index.js","source":"extensions/pixverse/index.ts"},{"output":"video-generation-provider.js","source":"extensions/pixverse/video-generation-provider.ts"}],"chunks":[{"output":"constants.js","sha256":"b75a588dbd52e65e90eb8bcd05e01e1d2944a3e58a4ab4a6024b98cfbedb2eff","facadeSource":"extensions/pixverse/constants.ts","sources":["extensions/pixverse/constants.ts"]},{"output":"index.js","sha256":"0bbca11d3450ab991f91d49007bb8447b30ed32fb0962ee0dfcc52d8654998d7","facadeSource":"extensions/pixverse/index.ts","sources":["extensions/pixverse/index.ts"]},{"output":"video-generation-provider.js","sha256":"354374cc78337e20d5eaa21332da99d1377e839d292f0346506c14c3ef3cca5c","facadeSource":"extensions/pixverse/video-generation-provider.ts","sources":["extensions/pixverse/video-generation-provider.ts"]}],"unrenderedSources":[]}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,32 @@
|
|
|
1
|
-
import { PIXVERSE_PROVIDER_ID } from "./constants.js";
|
|
2
|
-
import { buildPixVerseApiKeyAuthMethod } from "./onboard.js";
|
|
1
|
+
import { DEFAULT_PIXVERSE_REGION, PIXVERSE_BASE_URL_BY_REGION, PIXVERSE_DEFAULT_VIDEO_MODEL_REF, PIXVERSE_PROVIDER_ID, normalizePixVerseRegion } from "./constants.js";
|
|
3
2
|
import { buildPixVerseVideoGenerationProvider } from "./video-generation-provider.js";
|
|
4
3
|
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
4
|
+
import { applyAuthProfileConfig, buildApiKeyCredential, captureProviderApiKey, normalizeOptionalSecretInput, persistProviderApiKey } from "openclaw/plugin-sdk/provider-auth-api-key";
|
|
5
|
+
import { applyAgentDefaultMediaModel } from "openclaw/plugin-sdk/provider-onboard";
|
|
6
|
+
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
7
|
// extensions/pixverse/index.ts
|
|
8
|
+
const PROFILE_ID = `${PIXVERSE_PROVIDER_ID}:default`;
|
|
9
|
+
function applyPixVerseConfig(cfg, region, resetBaseUrl) {
|
|
10
|
+
const existingProvider = cfg.models?.providers?.["pixverse"] ?? {};
|
|
11
|
+
const selectedBaseUrl = PIXVERSE_BASE_URL_BY_REGION[region];
|
|
12
|
+
const baseUrl = resetBaseUrl ? selectedBaseUrl : normalizeOptionalString(existingProvider.baseUrl) ?? selectedBaseUrl;
|
|
13
|
+
const next = {
|
|
14
|
+
...cfg,
|
|
15
|
+
models: {
|
|
16
|
+
...cfg.models,
|
|
17
|
+
providers: {
|
|
18
|
+
...cfg.models?.providers,
|
|
19
|
+
[PIXVERSE_PROVIDER_ID]: {
|
|
20
|
+
...existingProvider,
|
|
21
|
+
baseUrl,
|
|
22
|
+
models: existingProvider.models ?? [],
|
|
23
|
+
region
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
return applyAgentDefaultMediaModel(next, "video", PIXVERSE_DEFAULT_VIDEO_MODEL_REF);
|
|
29
|
+
}
|
|
6
30
|
var pixverse_default = definePluginEntry({
|
|
7
31
|
id: PIXVERSE_PROVIDER_ID,
|
|
8
32
|
name: "PixVerse Provider",
|
|
@@ -13,7 +37,77 @@ var pixverse_default = definePluginEntry({
|
|
|
13
37
|
label: "PixVerse",
|
|
14
38
|
docsPath: "/providers/pixverse",
|
|
15
39
|
envVars: ["PIXVERSE_API_KEY"],
|
|
16
|
-
auth: [
|
|
40
|
+
auth: [{
|
|
41
|
+
id: "api-key",
|
|
42
|
+
label: "PixVerse API key",
|
|
43
|
+
hint: "Video generation API key",
|
|
44
|
+
kind: "api_key",
|
|
45
|
+
wizard: {
|
|
46
|
+
choiceId: "pixverse-api-key",
|
|
47
|
+
choiceLabel: "PixVerse API key",
|
|
48
|
+
choiceHint: "Prompts for International or CN endpoint",
|
|
49
|
+
groupId: "pixverse",
|
|
50
|
+
groupLabel: "PixVerse",
|
|
51
|
+
groupHint: "Video generation",
|
|
52
|
+
onboardingScopes: ["image-generation"]
|
|
53
|
+
},
|
|
54
|
+
async run(ctx) {
|
|
55
|
+
const { input, mode } = await captureProviderApiKey(ctx, {
|
|
56
|
+
token: normalizeOptionalSecretInput(ctx.opts?.pixverseApiKey) ?? normalizeOptionalSecretInput(ctx.opts?.token),
|
|
57
|
+
tokenProvider: normalizeOptionalSecretInput(ctx.opts?.pixverseApiKey) ? PIXVERSE_PROVIDER_ID : normalizeOptionalSecretInput(ctx.opts?.tokenProvider),
|
|
58
|
+
env: ctx.env,
|
|
59
|
+
expectedProviders: [PIXVERSE_PROVIDER_ID],
|
|
60
|
+
provider: PIXVERSE_PROVIDER_ID,
|
|
61
|
+
envLabel: "PIXVERSE_API_KEY",
|
|
62
|
+
promptMessage: "Enter PixVerse API key",
|
|
63
|
+
missingInputMessage: "Missing PixVerse API key."
|
|
64
|
+
});
|
|
65
|
+
const region = await ctx.prompter.select({
|
|
66
|
+
message: "Select PixVerse API region",
|
|
67
|
+
initialValue: DEFAULT_PIXVERSE_REGION,
|
|
68
|
+
options: [{
|
|
69
|
+
value: "international",
|
|
70
|
+
label: "International",
|
|
71
|
+
hint: PIXVERSE_BASE_URL_BY_REGION.international
|
|
72
|
+
}, {
|
|
73
|
+
value: "cn",
|
|
74
|
+
label: "CN",
|
|
75
|
+
hint: PIXVERSE_BASE_URL_BY_REGION.cn
|
|
76
|
+
}]
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
profiles: [{
|
|
80
|
+
profileId: PROFILE_ID,
|
|
81
|
+
credential: buildApiKeyCredential(PIXVERSE_PROVIDER_ID, input, void 0, mode ? {
|
|
82
|
+
secretInputMode: mode,
|
|
83
|
+
config: ctx.config
|
|
84
|
+
} : void 0)
|
|
85
|
+
}],
|
|
86
|
+
configPatch: applyPixVerseConfig(ctx.config, region, true),
|
|
87
|
+
notes: [`PixVerse endpoint: ${region === "cn" ? "CN" : "International"} (${PIXVERSE_BASE_URL_BY_REGION[region]})`]
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
async runNonInteractive(ctx) {
|
|
91
|
+
const resolved = await ctx.resolveApiKey({
|
|
92
|
+
provider: PIXVERSE_PROVIDER_ID,
|
|
93
|
+
flagValue: normalizeOptionalSecretInput(ctx.opts.pixverseApiKey),
|
|
94
|
+
flagName: "--pixverse-api-key",
|
|
95
|
+
envVar: "PIXVERSE_API_KEY"
|
|
96
|
+
});
|
|
97
|
+
if (!resolved) return null;
|
|
98
|
+
if (!await persistProviderApiKey(ctx, PROFILE_ID, {
|
|
99
|
+
provider: "pixverse",
|
|
100
|
+
resolved
|
|
101
|
+
})) return null;
|
|
102
|
+
const next = applyAuthProfileConfig(ctx.config, {
|
|
103
|
+
profileId: PROFILE_ID,
|
|
104
|
+
provider: PIXVERSE_PROVIDER_ID,
|
|
105
|
+
mode: "api_key"
|
|
106
|
+
});
|
|
107
|
+
const explicitRegion = normalizePixVerseRegion(ctx.opts.pixverseRegion);
|
|
108
|
+
return applyPixVerseConfig(next, explicitRegion ?? "international", explicitRegion !== void 0);
|
|
109
|
+
}
|
|
110
|
+
}]
|
|
17
111
|
});
|
|
18
112
|
api.registerVideoGenerationProvider(buildPixVerseVideoGenerationProvider());
|
|
19
113
|
}
|
|
@@ -5,7 +5,8 @@ import { bufferToBlobPart } from "openclaw/plugin-sdk/blob-runtime";
|
|
|
5
5
|
import { extensionForMime } from "openclaw/plugin-sdk/media-mime";
|
|
6
6
|
import { isProviderApiKeyConfiguredAsync } from "openclaw/plugin-sdk/provider-auth";
|
|
7
7
|
import { resolveApiKeyForProvider } from "openclaw/plugin-sdk/provider-auth-runtime";
|
|
8
|
-
import { assertOkOrThrowHttpError, createProviderOperationDeadline, pollProviderOperationJson,
|
|
8
|
+
import { assertOkOrThrowHttpError, createProviderOperationDeadline, pollProviderOperationJson, postJsonResponse, postMultipartRequest, readProviderJsonResponse, resolveProviderHttpRequestConfig, resolveProviderOperationTimeoutMs, sanitizeConfiguredModelProviderRequest } from "openclaw/plugin-sdk/provider-http";
|
|
9
|
+
import { normalizeVideoGenerationDuration } from "openclaw/plugin-sdk/video-generation";
|
|
9
10
|
// extensions/pixverse/video-generation-provider.ts
|
|
10
11
|
const DEFAULT_PIXVERSE_BASE_URL = PIXVERSE_BASE_URL_BY_REGION[DEFAULT_PIXVERSE_REGION];
|
|
11
12
|
const DEFAULT_PIXVERSE_QUALITY = "540p";
|
|
@@ -31,32 +32,6 @@ const PIXVERSE_QUALITIES = [
|
|
|
31
32
|
"720p",
|
|
32
33
|
"1080p"
|
|
33
34
|
];
|
|
34
|
-
function resolvePixVerseBaseUrl(req) {
|
|
35
|
-
const provider = req.cfg?.models?.providers?.[PIXVERSE_PROVIDER_ID];
|
|
36
|
-
const configuredBaseUrl = normalizeOptionalString(provider?.baseUrl);
|
|
37
|
-
if (configuredBaseUrl) return configuredBaseUrl;
|
|
38
|
-
const region = resolvePixVerseApiRegion(provider?.region);
|
|
39
|
-
return PIXVERSE_BASE_URL_BY_REGION[region];
|
|
40
|
-
}
|
|
41
|
-
function resolvePixVerseApiRegion(value) {
|
|
42
|
-
const region = normalizeOptionalString(value)?.toLowerCase();
|
|
43
|
-
const normalized = normalizePixVerseRegion(region);
|
|
44
|
-
if (normalized || region === void 0) return normalized ?? "international";
|
|
45
|
-
throw new Error(`Unsupported PixVerse API region "${region}". Use "international" or "cn".`);
|
|
46
|
-
}
|
|
47
|
-
function normalizePixVerseModel(model) {
|
|
48
|
-
return (normalizeOptionalString(model)?.replace(/^pixverse\//iu, ""))?.toLowerCase() || "v6";
|
|
49
|
-
}
|
|
50
|
-
function resolvePixVerseQuality(req) {
|
|
51
|
-
const requested = normalizeOptionalString(req.providerOptions?.quality) ?? normalizeOptionalString(req.resolution) ?? normalizeOptionalString(req.size);
|
|
52
|
-
if (!requested) return DEFAULT_PIXVERSE_QUALITY;
|
|
53
|
-
const normalized = requested.toLowerCase() === "480p" ? "540p" : requested.toLowerCase();
|
|
54
|
-
return PIXVERSE_QUALITIES.includes(normalized) ? normalized : DEFAULT_PIXVERSE_QUALITY;
|
|
55
|
-
}
|
|
56
|
-
function resolvePixVerseDurationSeconds(value) {
|
|
57
|
-
if (typeof value !== "number" || !Number.isFinite(value)) return 5;
|
|
58
|
-
return Math.max(1, Math.min(MAX_DURATION_SECONDS, Math.round(value)));
|
|
59
|
-
}
|
|
60
35
|
function readPixVerseSeed(value) {
|
|
61
36
|
return asSafeIntegerInRange(value, {
|
|
62
37
|
min: 0,
|
|
@@ -88,52 +63,12 @@ function readPixVerseInteger(value, label) {
|
|
|
88
63
|
return integer;
|
|
89
64
|
}
|
|
90
65
|
function readPixVerseStatus(payload) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
form.set("image_url", url);
|
|
98
|
-
return form;
|
|
99
|
-
}
|
|
100
|
-
if (!asset.buffer) throw new Error("PixVerse image-to-video input is missing image data.");
|
|
101
|
-
const mimeType = normalizeOptionalString(asset.mimeType) ?? "image/png";
|
|
102
|
-
const extension = extensionForMime(mimeType)?.slice(1) ?? "png";
|
|
103
|
-
const fileName = normalizeOptionalString(asset.fileName) ?? `image.${extension}`;
|
|
104
|
-
const file = new File([bufferToBlobPart(asset.buffer)], fileName, { type: mimeType });
|
|
105
|
-
form.set("image", file);
|
|
106
|
-
return form;
|
|
107
|
-
}
|
|
108
|
-
function buildVideoBody(req, model, imageId) {
|
|
109
|
-
const options = req.providerOptions ?? {};
|
|
110
|
-
const body = {
|
|
111
|
-
duration: resolvePixVerseDurationSeconds(req.durationSeconds),
|
|
112
|
-
model,
|
|
113
|
-
prompt: req.prompt,
|
|
114
|
-
quality: resolvePixVerseQuality(req)
|
|
115
|
-
};
|
|
116
|
-
if (imageId !== void 0) {
|
|
117
|
-
body.img_id = imageId;
|
|
118
|
-
body.motion_mode = normalizeOptionalString(options.motion_mode) ?? normalizeOptionalString(options.motionMode) ?? "normal";
|
|
119
|
-
} else body.aspect_ratio = normalizeOptionalString(req.aspectRatio) ?? "16:9";
|
|
120
|
-
const negativePrompt = normalizeOptionalString(options.negative_prompt) ?? normalizeOptionalString(options.negativePrompt);
|
|
121
|
-
if (negativePrompt) body.negative_prompt = negativePrompt;
|
|
122
|
-
const cameraMovement = normalizeOptionalString(options.camera_movement) ?? normalizeOptionalString(options.cameraMovement);
|
|
123
|
-
if (cameraMovement) body.camera_movement = cameraMovement;
|
|
124
|
-
const templateId = asFiniteNumber(options.template_id) ?? asFiniteNumber(options.templateId);
|
|
125
|
-
if (templateId != null) body.template_id = templateId;
|
|
126
|
-
const seed = readPixVerseSeed(options.seed);
|
|
127
|
-
if (seed !== void 0) body.seed = seed;
|
|
128
|
-
if (req.audio !== void 0) body.generate_audio_switch = req.audio;
|
|
129
|
-
return body;
|
|
130
|
-
}
|
|
131
|
-
function readPixVerseFailureMessage(payload) {
|
|
132
|
-
switch (readPixVerseStatus(payload)) {
|
|
133
|
-
case 7: return "PixVerse video generation failed content moderation";
|
|
134
|
-
case 8: return "PixVerse video generation failed";
|
|
135
|
-
case 6: return "PixVerse video generation was deleted before completion";
|
|
136
|
-
default: return;
|
|
66
|
+
const status = readPixVerseInteger(payload.status, "PixVerse video status response missing status");
|
|
67
|
+
switch (status) {
|
|
68
|
+
case 7: throw new Error("PixVerse video generation failed content moderation");
|
|
69
|
+
case 8: throw new Error("PixVerse video generation failed");
|
|
70
|
+
case 6: throw new Error("PixVerse video generation was deleted before completion");
|
|
71
|
+
default: return status;
|
|
137
72
|
}
|
|
138
73
|
}
|
|
139
74
|
function buildPixVerseModeCapabilities(imageToVideo = false) {
|
|
@@ -197,15 +132,22 @@ function buildPixVerseVideoGenerationProvider() {
|
|
|
197
132
|
store: req.authStore
|
|
198
133
|
});
|
|
199
134
|
if (!auth.apiKey) throw new Error("PixVerse API key missing");
|
|
200
|
-
const model =
|
|
135
|
+
const model = normalizeOptionalString(req.model)?.replace(/^pixverse\//iu, "").toLowerCase() || "v6";
|
|
201
136
|
const fetchFn = fetch;
|
|
202
137
|
const providerConfig = req.cfg?.models?.providers?.[PIXVERSE_PROVIDER_ID];
|
|
203
138
|
const deadline = createProviderOperationDeadline({
|
|
204
139
|
timeoutMs: req.timeoutMs,
|
|
205
140
|
label: "PixVerse video generation"
|
|
206
141
|
});
|
|
142
|
+
let configuredBaseUrl = normalizeOptionalString(providerConfig?.baseUrl);
|
|
143
|
+
if (!configuredBaseUrl) {
|
|
144
|
+
const region = normalizeOptionalString(providerConfig?.region)?.toLowerCase();
|
|
145
|
+
const normalized = normalizePixVerseRegion(region);
|
|
146
|
+
if (!normalized && region !== void 0) throw new Error(`Unsupported PixVerse API region "${region}". Use "international" or "cn".`);
|
|
147
|
+
configuredBaseUrl = PIXVERSE_BASE_URL_BY_REGION[normalized ?? "international"];
|
|
148
|
+
}
|
|
207
149
|
const { baseUrl, allowPrivateNetwork, headers, dispatcherPolicy } = resolveProviderHttpRequestConfig({
|
|
208
|
-
baseUrl:
|
|
150
|
+
baseUrl: configuredBaseUrl,
|
|
209
151
|
defaultBaseUrl: DEFAULT_PIXVERSE_BASE_URL,
|
|
210
152
|
request: sanitizeConfiguredModelProviderRequest(providerConfig?.request),
|
|
211
153
|
defaultHeaders: { "API-KEY": auth.apiKey },
|
|
@@ -216,10 +158,22 @@ function buildPixVerseVideoGenerationProvider() {
|
|
|
216
158
|
const image = req.inputImages?.[0];
|
|
217
159
|
let imageId;
|
|
218
160
|
if (image) {
|
|
161
|
+
const uploadHeaders = buildPixVerseHeaders(headers);
|
|
162
|
+
const form = new FormData();
|
|
163
|
+
const imageUrl = normalizeOptionalString(image.url);
|
|
164
|
+
if (imageUrl) form.set("image_url", imageUrl);
|
|
165
|
+
else {
|
|
166
|
+
if (!image.buffer) throw new Error("PixVerse image-to-video input is missing image data.");
|
|
167
|
+
const mimeType = normalizeOptionalString(image.mimeType) ?? "image/png";
|
|
168
|
+
const extension = extensionForMime(mimeType)?.slice(1) ?? "png";
|
|
169
|
+
const fileName = normalizeOptionalString(image.fileName) ?? `image.${extension}`;
|
|
170
|
+
const file = new File([bufferToBlobPart(image.buffer)], fileName, { type: mimeType });
|
|
171
|
+
form.set("image", file);
|
|
172
|
+
}
|
|
219
173
|
const upload = await postMultipartRequest({
|
|
220
174
|
url: `${baseUrl}/image/upload`,
|
|
221
|
-
headers:
|
|
222
|
-
body:
|
|
175
|
+
headers: uploadHeaders,
|
|
176
|
+
body: form,
|
|
223
177
|
timeoutMs: resolveProviderOperationTimeoutMs({
|
|
224
178
|
deadline,
|
|
225
179
|
defaultTimeoutMs: DEFAULT_TIMEOUT_MS
|
|
@@ -235,11 +189,35 @@ function buildPixVerseVideoGenerationProvider() {
|
|
|
235
189
|
await upload.release();
|
|
236
190
|
}
|
|
237
191
|
}
|
|
192
|
+
const options = req.providerOptions ?? {};
|
|
193
|
+
const duration = Math.min(MAX_DURATION_SECONDS, normalizeVideoGenerationDuration({ durationSeconds: req.durationSeconds }) ?? 5);
|
|
194
|
+
const requestedQuality = normalizeOptionalString(req.providerOptions?.quality) ?? normalizeOptionalString(req.resolution) ?? normalizeOptionalString(req.size);
|
|
195
|
+
const normalizedQuality = requestedQuality?.toLowerCase() === "480p" ? "540p" : requestedQuality?.toLowerCase();
|
|
196
|
+
const body = {
|
|
197
|
+
duration,
|
|
198
|
+
model,
|
|
199
|
+
prompt: req.prompt,
|
|
200
|
+
quality: normalizedQuality && PIXVERSE_QUALITIES.includes(normalizedQuality) ? normalizedQuality : DEFAULT_PIXVERSE_QUALITY
|
|
201
|
+
};
|
|
202
|
+
if (imageId !== void 0) {
|
|
203
|
+
body.img_id = imageId;
|
|
204
|
+
body.motion_mode = normalizeOptionalString(options.motion_mode) ?? normalizeOptionalString(options.motionMode) ?? "normal";
|
|
205
|
+
} else body.aspect_ratio = normalizeOptionalString(req.aspectRatio) ?? "16:9";
|
|
206
|
+
const negativePrompt = normalizeOptionalString(options.negative_prompt) ?? normalizeOptionalString(options.negativePrompt);
|
|
207
|
+
if (negativePrompt) body.negative_prompt = negativePrompt;
|
|
208
|
+
const cameraMovement = normalizeOptionalString(options.camera_movement) ?? normalizeOptionalString(options.cameraMovement);
|
|
209
|
+
if (cameraMovement) body.camera_movement = cameraMovement;
|
|
210
|
+
const templateId = asFiniteNumber(options.template_id) ?? asFiniteNumber(options.templateId);
|
|
211
|
+
if (templateId != null) body.template_id = templateId;
|
|
212
|
+
const seed = readPixVerseSeed(options.seed);
|
|
213
|
+
if (seed !== void 0) body.seed = seed;
|
|
214
|
+
if (req.audio !== void 0) body.generate_audio_switch = req.audio;
|
|
238
215
|
const endpoint = imageId === void 0 ? "/video/text/generate" : "/video/img/generate";
|
|
239
|
-
const
|
|
216
|
+
const videoId = readPixVerseInteger(readPixVerseSuccess(await postJsonResponse({
|
|
240
217
|
url: `${baseUrl}${endpoint}`,
|
|
218
|
+
errorLabel: "PixVerse video generation failed",
|
|
241
219
|
headers: buildPixVerseHeaders(headers, "application/json"),
|
|
242
|
-
body
|
|
220
|
+
body,
|
|
243
221
|
timeoutMs: resolveProviderOperationTimeoutMs({
|
|
244
222
|
deadline,
|
|
245
223
|
defaultTimeoutMs: DEFAULT_TIMEOUT_MS
|
|
@@ -247,51 +225,44 @@ function buildPixVerseVideoGenerationProvider() {
|
|
|
247
225
|
fetchFn,
|
|
248
226
|
allowPrivateNetwork,
|
|
249
227
|
dispatcherPolicy
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
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
|
-
}],
|
|
283
|
-
model,
|
|
228
|
+
}), "PixVerse video generation failed").video_id, "PixVerse video generation response missing video_id");
|
|
229
|
+
const readResult = (payload) => readPixVerseSuccess(payload, "PixVerse video status request failed");
|
|
230
|
+
const completed = readResult(await pollProviderOperationJson({
|
|
231
|
+
url: `${baseUrl}/video/result/${videoId}`,
|
|
232
|
+
headers: () => buildPixVerseHeaders(headers),
|
|
233
|
+
deadline,
|
|
234
|
+
defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
|
|
235
|
+
fetchFn,
|
|
236
|
+
maxAttempts: MAX_POLL_ATTEMPTS,
|
|
237
|
+
pollIntervalMs: POLL_INTERVAL_MS,
|
|
238
|
+
requestFailedMessage: "PixVerse video status request failed",
|
|
239
|
+
timeoutMessage: `PixVerse video generation task ${videoId} did not finish in time`,
|
|
240
|
+
isComplete: (candidate) => readPixVerseStatus(readResult(candidate)) === 1,
|
|
241
|
+
allowPrivateNetwork,
|
|
242
|
+
dispatcherPolicy
|
|
243
|
+
}));
|
|
244
|
+
const url = normalizeOptionalString(completed.url);
|
|
245
|
+
if (!url) throw new Error("PixVerse video generation completed without output URL");
|
|
246
|
+
return {
|
|
247
|
+
videos: [{
|
|
248
|
+
url,
|
|
249
|
+
mimeType: "video/mp4",
|
|
250
|
+
fileName: "video-1.mp4",
|
|
284
251
|
metadata: {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
seed: readPixVerseSeed(completed.seed),
|
|
289
|
-
size: asFiniteNumber(completed.size)
|
|
252
|
+
sourceUrl: url,
|
|
253
|
+
outputWidth: asFiniteNumber(completed.outputWidth),
|
|
254
|
+
outputHeight: asFiniteNumber(completed.outputHeight)
|
|
290
255
|
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
256
|
+
}],
|
|
257
|
+
model,
|
|
258
|
+
metadata: {
|
|
259
|
+
endpoint,
|
|
260
|
+
videoId,
|
|
261
|
+
status: readPixVerseStatus(completed),
|
|
262
|
+
seed: readPixVerseSeed(completed.seed),
|
|
263
|
+
size: asFiniteNumber(completed.size)
|
|
264
|
+
}
|
|
265
|
+
};
|
|
295
266
|
}
|
|
296
267
|
};
|
|
297
268
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/pixverse-provider",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.11.5-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.11.5-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.11.5-beta.1"
|
|
30
30
|
},
|
|
31
31
|
"build": {
|
|
32
|
-
"openclawVersion": "2026.
|
|
32
|
+
"openclawVersion": "2026.11.5-beta.1",
|
|
33
33
|
"bundledDist": false
|
|
34
34
|
},
|
|
35
35
|
"release": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"entries":[{"output":"constants.js","source":"extensions/pixverse/constants.ts"},{"output":"index.js","source":"extensions/pixverse/index.ts"},{"output":"onboard.js","source":"extensions/pixverse/onboard.ts"},{"output":"video-generation-provider.js","source":"extensions/pixverse/video-generation-provider.ts"}],"chunks":[{"output":"constants.js","sha256":"b75a588dbd52e65e90eb8bcd05e01e1d2944a3e58a4ab4a6024b98cfbedb2eff","facadeSource":"extensions/pixverse/constants.ts","sources":["extensions/pixverse/constants.ts"]},{"output":"index.js","sha256":"f24572bc5b4de2498c9ff5b85b0764ebc1185337cd2741e370a23732af9dfa2d","facadeSource":"extensions/pixverse/index.ts","sources":["extensions/pixverse/index.ts"]},{"output":"onboard.js","sha256":"05fdb6d5a817f1746ae2a57fb7449d190be2ea4b008ac70ed19e549d6c12472a","facadeSource":"extensions/pixverse/onboard.ts","sources":["extensions/pixverse/onboard.ts"]},{"output":"video-generation-provider.js","sha256":"138360b4d1f3e30b797c9a0f20ecf89c2f4565a100c81d9d56ed478e44917bf7","facadeSource":"extensions/pixverse/video-generation-provider.ts","sources":["extensions/pixverse/video-generation-provider.ts"]}],"unrenderedSources":[]}
|
package/dist/onboard.js
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_PIXVERSE_REGION, PIXVERSE_BASE_URL_BY_REGION, PIXVERSE_DEFAULT_VIDEO_MODEL_REF, PIXVERSE_PROVIDER_ID, normalizePixVerseRegion } from "./constants.js";
|
|
2
|
-
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
|
-
import { applyAuthProfileConfig, buildApiKeyCredential, captureProviderApiKey, normalizeOptionalSecretInput, persistProviderApiKey } from "openclaw/plugin-sdk/provider-auth-api-key";
|
|
4
|
-
// extensions/pixverse/onboard.ts
|
|
5
|
-
const PROFILE_ID = `${PIXVERSE_PROVIDER_ID}:default`;
|
|
6
|
-
function applyPixVerseConfig(cfg, region, resetBaseUrl) {
|
|
7
|
-
const existingProvider = cfg.models?.providers?.["pixverse"] ?? {};
|
|
8
|
-
const selectedBaseUrl = PIXVERSE_BASE_URL_BY_REGION[region];
|
|
9
|
-
const baseUrl = resetBaseUrl ? selectedBaseUrl : normalizeOptionalString(existingProvider.baseUrl) ?? selectedBaseUrl;
|
|
10
|
-
const next = {
|
|
11
|
-
...cfg,
|
|
12
|
-
models: {
|
|
13
|
-
...cfg.models,
|
|
14
|
-
providers: {
|
|
15
|
-
...cfg.models?.providers,
|
|
16
|
-
[PIXVERSE_PROVIDER_ID]: {
|
|
17
|
-
...existingProvider,
|
|
18
|
-
baseUrl,
|
|
19
|
-
models: existingProvider.models ?? [],
|
|
20
|
-
region
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
if (next.agents?.defaults?.mediaModels?.video) return next;
|
|
26
|
-
return {
|
|
27
|
-
...next,
|
|
28
|
-
agents: {
|
|
29
|
-
...next.agents,
|
|
30
|
-
defaults: {
|
|
31
|
-
...next.agents?.defaults,
|
|
32
|
-
mediaModels: {
|
|
33
|
-
...next.agents?.defaults?.mediaModels,
|
|
34
|
-
video: { primary: PIXVERSE_DEFAULT_VIDEO_MODEL_REF }
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
}
|
|
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({
|
|
52
|
-
message: "Select PixVerse API region",
|
|
53
|
-
initialValue: DEFAULT_PIXVERSE_REGION,
|
|
54
|
-
options: [{
|
|
55
|
-
value: "international",
|
|
56
|
-
label: "International",
|
|
57
|
-
hint: PIXVERSE_BASE_URL_BY_REGION.international
|
|
58
|
-
}, {
|
|
59
|
-
value: "cn",
|
|
60
|
-
label: "CN",
|
|
61
|
-
hint: PIXVERSE_BASE_URL_BY_REGION.cn
|
|
62
|
-
}]
|
|
63
|
-
});
|
|
64
|
-
return {
|
|
65
|
-
profiles: [{
|
|
66
|
-
profileId: PROFILE_ID,
|
|
67
|
-
credential: buildApiKeyCredential(PIXVERSE_PROVIDER_ID, input, void 0, mode ? {
|
|
68
|
-
secretInputMode: mode,
|
|
69
|
-
config: ctx.config
|
|
70
|
-
} : void 0)
|
|
71
|
-
}],
|
|
72
|
-
configPatch: applyPixVerseConfig(ctx.config, region, true),
|
|
73
|
-
notes: [`PixVerse endpoint: ${region === "cn" ? "CN" : "International"} (${PIXVERSE_BASE_URL_BY_REGION[region]})`]
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
async function runPixVerseApiKeyAuthNonInteractive(ctx) {
|
|
77
|
-
const resolved = await ctx.resolveApiKey({
|
|
78
|
-
provider: PIXVERSE_PROVIDER_ID,
|
|
79
|
-
flagValue: normalizeOptionalSecretInput(ctx.opts.pixverseApiKey),
|
|
80
|
-
flagName: "--pixverse-api-key",
|
|
81
|
-
envVar: "PIXVERSE_API_KEY"
|
|
82
|
-
});
|
|
83
|
-
if (!resolved) return null;
|
|
84
|
-
if (!await persistProviderApiKey(ctx, PROFILE_ID, {
|
|
85
|
-
provider: "pixverse",
|
|
86
|
-
resolved
|
|
87
|
-
})) return null;
|
|
88
|
-
const next = applyAuthProfileConfig(ctx.config, {
|
|
89
|
-
profileId: PROFILE_ID,
|
|
90
|
-
provider: PIXVERSE_PROVIDER_ID,
|
|
91
|
-
mode: "api_key"
|
|
92
|
-
});
|
|
93
|
-
const explicitRegion = normalizePixVerseRegion(ctx.opts.pixverseRegion);
|
|
94
|
-
return applyPixVerseConfig(next, explicitRegion ?? "international", explicitRegion !== void 0);
|
|
95
|
-
}
|
|
96
|
-
function buildPixVerseApiKeyAuthMethod() {
|
|
97
|
-
return {
|
|
98
|
-
id: "api-key",
|
|
99
|
-
label: "PixVerse API key",
|
|
100
|
-
hint: "Video generation API key",
|
|
101
|
-
kind: "api_key",
|
|
102
|
-
wizard: {
|
|
103
|
-
choiceId: "pixverse-api-key",
|
|
104
|
-
choiceLabel: "PixVerse API key",
|
|
105
|
-
choiceHint: "Prompts for International or CN endpoint",
|
|
106
|
-
groupId: "pixverse",
|
|
107
|
-
groupLabel: "PixVerse",
|
|
108
|
-
groupHint: "Video generation",
|
|
109
|
-
onboardingScopes: ["image-generation"]
|
|
110
|
-
},
|
|
111
|
-
run: runPixVerseApiKeyAuth,
|
|
112
|
-
runNonInteractive: runPixVerseApiKeyAuthNonInteractive
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
export { buildPixVerseApiKeyAuthMethod };
|