veogent 1.5.1 → 1.6.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/README.md +36 -9
- package/index.js +87 -21
- package/package.json +1 -1
- package/skills/SKILL.md +34 -7
package/README.md
CHANGED
|
@@ -98,20 +98,23 @@ veogent create-scene --project <projectId> --chapter <chapterId> \
|
|
|
98
98
|
--lang English --material CINEMATIC --scenes 5 --wait
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
#### Phase 3: Generate Images + Videos
|
|
101
|
+
#### Phase 3: Generate Images + Videos (Async Polling)
|
|
102
102
|
|
|
103
103
|
```bash
|
|
104
|
-
#
|
|
104
|
+
# 1. Trigger generation (without --wait) to avoid locking your terminal
|
|
105
105
|
veogent batch-request --type GENERATE_IMAGES \
|
|
106
|
-
--project <projectId> --chapter <chapterId> --all
|
|
107
|
-
--orientation VERTICAL --wait
|
|
106
|
+
--project <projectId> --chapter <chapterId> --all --orientation VERTICAL
|
|
108
107
|
|
|
109
|
-
#
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
108
|
+
# 2. Extract `requestId` from the output
|
|
109
|
+
# 3. Poll status asynchronously:
|
|
110
|
+
veogent request-status --id <requestId>
|
|
111
|
+
# ... loop until requestStatus === "COMPLETED"
|
|
112
|
+
|
|
113
|
+
# Repeat for GENERATE_VIDEO once images are ready
|
|
113
114
|
```
|
|
114
115
|
|
|
116
|
+
> **Tip for Agents:** While the `--wait` flag exists, using `request-status` is recommended so you don't lock your main process for the 5-10 minutes it takes to render a video.
|
|
117
|
+
|
|
115
118
|
#### Phase 4: QA + Fix Loop
|
|
116
119
|
|
|
117
120
|
```bash
|
|
@@ -187,13 +190,15 @@ veogent request --type GENERATE_VIDEO \
|
|
|
187
190
|
|
|
188
191
|
| Command | Description |
|
|
189
192
|
|---------|-------------|
|
|
190
|
-
| `request` | Create a single generation job (`GENERATE_IMAGES` / `GENERATE_VIDEO`) |
|
|
193
|
+
| `request` | Create a single generation job (`GENERATE_IMAGES` / `GENERATE_VIDEO` / `UPSCALE_VIDEO`) |
|
|
191
194
|
| `batch-request` | Batch generation for multiple/all scenes (`--all`) |
|
|
192
195
|
| `requests` | List existing generation jobs |
|
|
196
|
+
| `request-status` | Check a specific job by request ID (includes asset URL) |
|
|
193
197
|
| `failed-requests` | List failed requests for a chapter |
|
|
194
198
|
| `wait-images` | Poll until all image jobs finish |
|
|
195
199
|
| `wait-videos` | Poll until all video jobs finish |
|
|
196
200
|
| `queue-status` | Current queue/concurrency status |
|
|
201
|
+
| `download-upscale` | Download 4K upscaled video as `.mp4` (decodes base64 from flow-media) |
|
|
197
202
|
|
|
198
203
|
### Monitoring
|
|
199
204
|
|
|
@@ -201,6 +206,7 @@ veogent request --type GENERATE_VIDEO \
|
|
|
201
206
|
|---------|-------------|
|
|
202
207
|
| `scene-status` | Scene-level image+video status with asset URLs |
|
|
203
208
|
| `workflow-status` | Full snapshot: scenes + requests + assets (best for agents) |
|
|
209
|
+
| `request-status` | Check a specific job by request ID |
|
|
204
210
|
|
|
205
211
|
### YouTube
|
|
206
212
|
|
|
@@ -245,6 +251,27 @@ Uses sceneA's image as start frame, sceneB's image as end frame. Both scenes mus
|
|
|
245
251
|
|
|
246
252
|
---
|
|
247
253
|
|
|
254
|
+
## Video Upscale (4K)
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
# 1. Trigger upscale
|
|
258
|
+
veogent request --type UPSCALE_VIDEO \
|
|
259
|
+
--project X --chapter Y --scene Z \
|
|
260
|
+
--orientation VERTICAL --resolution VIDEO_RESOLUTION_4K
|
|
261
|
+
|
|
262
|
+
# 2. Poll status by request ID
|
|
263
|
+
veogent request-status --id <requestId>
|
|
264
|
+
|
|
265
|
+
# 3. Download the upscaled video
|
|
266
|
+
veogent download-upscale \
|
|
267
|
+
--project X --chapter Y --scene Z \
|
|
268
|
+
--orientation VERTICAL --out ./scene_4k.mp4
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
> `download-upscale` calls `/app/scene/flow-media`, decodes the base64 `encodedVideo`, and writes a `.mp4` file.
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
248
275
|
## Concurrency
|
|
249
276
|
|
|
250
277
|
Maximum **5** concurrent requests. If queue is full (E10071), CLI auto-retries once after 30s.
|
package/index.js
CHANGED
|
@@ -747,8 +747,8 @@ program
|
|
|
747
747
|
// --- Execution Request (Generate Image / Video) ---
|
|
748
748
|
program
|
|
749
749
|
.command('request')
|
|
750
|
-
.description('Create a job request (GENERATE_IMAGES, GENERATE_VIDEO)')
|
|
751
|
-
.requiredOption('--type <type>', 'Request type (e.g., GENERATE_IMAGES, GENERATE_VIDEO)')
|
|
750
|
+
.description('Create a job request (GENERATE_IMAGES, GENERATE_VIDEO, UPSCALE_VIDEO). Use UPSCALE_VIDEO to upscale a rendered video to 4K resolution.')
|
|
751
|
+
.requiredOption('--type <type>', 'Request type (e.g., GENERATE_IMAGES, GENERATE_VIDEO, UPSCALE_VIDEO)')
|
|
752
752
|
.requiredOption('--project <project>', 'Project ID')
|
|
753
753
|
.requiredOption('--chapter <chapter>', 'Chapter ID')
|
|
754
754
|
.requiredOption('--scene <scene>', 'Scene ID')
|
|
@@ -757,6 +757,7 @@ program
|
|
|
757
757
|
.option('--videomodel <videomodel>', 'Video Model (veo_3_1_fast, veo_3_1_fast_r2v). Default: veo_3_1_fast', 'veo_3_1_fast')
|
|
758
758
|
.option('--speed <speed>', 'Video Speed (normal, timelapse, slowmotion)', 'normal')
|
|
759
759
|
.option('--endscene <endscene>', 'End Scene ID for continuous video generation')
|
|
760
|
+
.option('--resolution <resolution>', 'Resolution for UPSCALE_VIDEO (e.g. VIDEO_RESOLUTION_4K)', 'VIDEO_RESOLUTION_4K')
|
|
760
761
|
.option('--wait', 'Wait for request to complete before returning')
|
|
761
762
|
.action(async (options) => {
|
|
762
763
|
try {
|
|
@@ -804,8 +805,9 @@ program
|
|
|
804
805
|
payload.orientation = options.orientation || 'HORIZONTAL';
|
|
805
806
|
payload.imageModel = options.imagemodel;
|
|
806
807
|
}
|
|
807
|
-
if (['
|
|
808
|
-
payload.orientation = options.orientation || '
|
|
808
|
+
if (['UPSCALE_VIDEO'].includes(options.type)) {
|
|
809
|
+
payload.orientation = options.orientation || 'VERTICAL'; // Upscale defaults to VERTICAL
|
|
810
|
+
payload.resolution = options.resolution || 'VIDEO_RESOLUTION_4K';
|
|
809
811
|
}
|
|
810
812
|
|
|
811
813
|
const data = await api.post('/app/request', payload);
|
|
@@ -1057,35 +1059,64 @@ program
|
|
|
1057
1059
|
|
|
1058
1060
|
program
|
|
1059
1061
|
.command('request-status')
|
|
1060
|
-
.description('Get status of a specific request by ID')
|
|
1062
|
+
.description('Get status of a specific request by ID. For GENERATE_VIDEO/GENERATE_IMAGES, falls back to assets endpoint for output URL. UPSCALE_VIDEO output URL is read directly from the request object.')
|
|
1061
1063
|
.requiredOption('--id <requestId>', 'Request ID to check')
|
|
1062
1064
|
.action(async (options) => {
|
|
1063
1065
|
try {
|
|
1064
|
-
const data = await api.get(
|
|
1065
|
-
|
|
1066
|
-
items = Array.isArray(items) ? items : (items?.items || []);
|
|
1066
|
+
const data = await api.get(`/app/standalone/request/${options.id}`);
|
|
1067
|
+
const found = unwrapData(data);
|
|
1067
1068
|
|
|
1068
|
-
const found = items.find((r) => r?.id === options.id || r?.requestId === options.id);
|
|
1069
1069
|
if (!found) {
|
|
1070
1070
|
emitJson({ status: 'error', code: 'REQUEST_NOT_FOUND', message: `No request found with ID: ${options.id}` });
|
|
1071
1071
|
return;
|
|
1072
1072
|
}
|
|
1073
1073
|
|
|
1074
|
-
const
|
|
1074
|
+
const requestStatus = String(found?.status || '').toUpperCase();
|
|
1075
|
+
const type = found?.type || null;
|
|
1076
|
+
const projectId = found?.projectId || found?.project_id || null;
|
|
1077
|
+
const chapterId = found?.chapterId || found?.chapter_id || null;
|
|
1078
|
+
const sceneId = found?.sceneId || found?.scene_id || null;
|
|
1079
|
+
|
|
1080
|
+
let imageAsset = { url: found?.imageVerticalUri || found?.imageHorizontalUri || found?.imageUrl || null };
|
|
1081
|
+
// UPSCALE_VIDEO: output URL lives directly on the request object (not in assets endpoint)
|
|
1082
|
+
let videoAsset = { url: found?.videoVerticalUri || found?.videoHorizontalUri || found?.videoUrl || found?.outputUrl || null };
|
|
1083
|
+
|
|
1084
|
+
// For GENERATE_VIDEO only: fallback to assets endpoint if URL not on request object
|
|
1085
|
+
if (type === 'GENERATE_VIDEO' && projectId && chapterId && sceneId && !videoAsset.url) {
|
|
1086
|
+
try {
|
|
1087
|
+
const assetData = unwrapData(await api.get(`/app/request/assets/${projectId}/${chapterId}/${sceneId}?type=GENERATE_VIDEO`));
|
|
1088
|
+
const assetItems = Array.isArray(assetData) ? assetData : (assetData?.items || []);
|
|
1089
|
+
const matched = assetItems.find((a) => a?.id === options.id || a?.requestId === options.id)
|
|
1090
|
+
|| assetItems.find((a) => String(a?.status || '').toUpperCase() === 'COMPLETED');
|
|
1091
|
+
if (matched) {
|
|
1092
|
+
videoAsset = { url: matched?.videoVerticalUri || matched?.videoHorizontalUri || matched?.videoUrl || matched?.outputUrl || null };
|
|
1093
|
+
}
|
|
1094
|
+
} catch { /* asset fetch optional */ }
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
// For image type: fetch asset URL if not present
|
|
1098
|
+
if (type === 'GENERATE_IMAGES' && projectId && chapterId && sceneId && !imageAsset.url) {
|
|
1099
|
+
try {
|
|
1100
|
+
const assetData = unwrapData(await api.get(`/app/request/assets/${projectId}/${chapterId}/${sceneId}?type=GENERATE_IMAGES`));
|
|
1101
|
+
const assetItems = Array.isArray(assetData) ? assetData : (assetData?.items || []);
|
|
1102
|
+
const matched = assetItems.find((a) => a?.id === options.id || a?.requestId === options.id)
|
|
1103
|
+
|| assetItems.find((a) => String(a?.status || '').toUpperCase() === 'COMPLETED');
|
|
1104
|
+
if (matched) {
|
|
1105
|
+
imageAsset = { url: matched?.imageVerticalUri || matched?.imageHorizontalUri || matched?.imageUrl || matched?.outputUrl || null };
|
|
1106
|
+
}
|
|
1107
|
+
} catch { /* asset fetch optional */ }
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1075
1110
|
const result = {
|
|
1076
1111
|
status: 'success',
|
|
1077
1112
|
requestId: found?.id || found?.requestId,
|
|
1078
|
-
type
|
|
1079
|
-
requestStatus
|
|
1080
|
-
sceneId
|
|
1081
|
-
chapterId
|
|
1082
|
-
projectId
|
|
1083
|
-
image:
|
|
1084
|
-
|
|
1085
|
-
},
|
|
1086
|
-
video: {
|
|
1087
|
-
url: found?.videoVerticalUri || found?.videoHorizontalUri || found?.videoUrl || found?.outputUrl || null,
|
|
1088
|
-
},
|
|
1113
|
+
type,
|
|
1114
|
+
requestStatus,
|
|
1115
|
+
sceneId,
|
|
1116
|
+
chapterId,
|
|
1117
|
+
projectId,
|
|
1118
|
+
image: imageAsset,
|
|
1119
|
+
video: videoAsset,
|
|
1089
1120
|
createdAt: found?.createdAt || found?.created_at || null,
|
|
1090
1121
|
completedAt: found?.completedAt || found?.updatedAt || null,
|
|
1091
1122
|
raw: found,
|
|
@@ -1109,6 +1140,41 @@ program
|
|
|
1109
1140
|
}
|
|
1110
1141
|
});
|
|
1111
1142
|
|
|
1143
|
+
program
|
|
1144
|
+
.command('download-upscale')
|
|
1145
|
+
.description('Download the 4K upscaled video for a scene. Calls /app/scene/flow-media to retrieve the base64-encoded video and saves it as an .mp4 file.')
|
|
1146
|
+
.requiredOption('--project <project>', 'Project ID')
|
|
1147
|
+
.requiredOption('--chapter <chapter>', 'Chapter ID')
|
|
1148
|
+
.requiredOption('--scene <scene>', 'Scene ID')
|
|
1149
|
+
.option('--orientation <orientation>', 'Orientation to download (VERTICAL, HORIZONTAL)', 'VERTICAL')
|
|
1150
|
+
.option('--out <path>', 'Output file path (default: ./<sceneId>_upscale.mp4)')
|
|
1151
|
+
.action(async (options) => {
|
|
1152
|
+
try {
|
|
1153
|
+
const orientation = options.orientation.toLowerCase(); // Backend expects lowercase (e.g. 'vertical')
|
|
1154
|
+
humanLog(`⏳ Fetching upscaled video from flow-media...`);
|
|
1155
|
+
|
|
1156
|
+
const data = await api.get(`/app/scene/flow-media/${options.project}/${options.chapter}/${options.scene}/${orientation}`);
|
|
1157
|
+
const raw = unwrapData(data);
|
|
1158
|
+
|
|
1159
|
+
// Backend returns { video: { encodedVideo, ... } } or flat { encodedVideo }
|
|
1160
|
+
const encodedVideo = raw?.video?.encodedVideo || raw?.encodedVideo || null;
|
|
1161
|
+
|
|
1162
|
+
if (!encodedVideo) {
|
|
1163
|
+
emitJson({ status: 'error', code: 'NO_VIDEO_DATA', message: 'No encodedVideo in response. The upscale may not be ready yet.', raw });
|
|
1164
|
+
return;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
const outPath = options.out || `./${options.scene}_upscale.mp4`;
|
|
1168
|
+
const { writeFileSync } = await import('fs');
|
|
1169
|
+
writeFileSync(outPath, Buffer.from(encodedVideo, 'base64'));
|
|
1170
|
+
|
|
1171
|
+
humanLog(`✅ Saved upscaled video to: ${outPath}`);
|
|
1172
|
+
emitJson({ status: 'success', file: outPath, sceneId: options.scene, orientation });
|
|
1173
|
+
} catch (error) {
|
|
1174
|
+
emitJson({ status: 'error', ...formatCliError(error) });
|
|
1175
|
+
}
|
|
1176
|
+
});
|
|
1177
|
+
|
|
1112
1178
|
program
|
|
1113
1179
|
.command('failed-requests')
|
|
1114
1180
|
.description('List failed requests for a project/chapter (agent helper)')
|
package/package.json
CHANGED
package/skills/SKILL.md
CHANGED
|
@@ -57,15 +57,20 @@ veogent characters <projectId> # poll until allReady === true
|
|
|
57
57
|
|
|
58
58
|
NEVER skip `create-chapter-content` — always let VEOGENT AI generate the storyboard.
|
|
59
59
|
|
|
60
|
-
### Phase 3: Generate Images + Videos
|
|
60
|
+
### Phase 3: Generate Images + Videos (Async)
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
# 1. Trigger batch generation (without --wait)
|
|
64
|
+
veogent batch-request --type GENERATE_IMAGES --project X --chapter Y --all --orientation VERTICAL
|
|
65
|
+
|
|
66
|
+
# 2. Extract the request IDs from the output
|
|
67
|
+
# 3. Poll their status asynchronously without blocking your main process
|
|
68
|
+
veogent request-status --id <requestId>
|
|
69
|
+
# ... loop until requestStatus === "COMPLETED"
|
|
67
70
|
```
|
|
68
71
|
|
|
72
|
+
*Note: You CAN use the `--wait` flag to make the CLI block until finished, but using `request-status` is better for true asynchronous agent pipelines so you don't lock your process.*
|
|
73
|
+
|
|
69
74
|
### Phase 4: QA + Fix Loop
|
|
70
75
|
|
|
71
76
|
```bash
|
|
@@ -196,6 +201,25 @@ veogent request --type GENERATE_VIDEO --project X --chapter Y --scene sceneA \
|
|
|
196
201
|
```
|
|
197
202
|
Uses sceneA image → sceneB image as start/end frames. Both must have successful images. Only `veo_3_1_fast`.
|
|
198
203
|
|
|
204
|
+
### Video Upscale (4K)
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
# 1. Trigger upscale
|
|
208
|
+
veogent request --type UPSCALE_VIDEO \
|
|
209
|
+
--project X --chapter Y --scene Z \
|
|
210
|
+
--orientation VERTICAL --resolution VIDEO_RESOLUTION_4K
|
|
211
|
+
|
|
212
|
+
# 2. Poll until COMPLETED
|
|
213
|
+
veogent request-status --id <requestId>
|
|
214
|
+
|
|
215
|
+
# 3. Download the upscaled .mp4 (reads from flow-media, decodes base64)
|
|
216
|
+
veogent download-upscale \
|
|
217
|
+
--project X --chapter Y --scene Z \
|
|
218
|
+
--orientation VERTICAL --out ./scene_4k.mp4
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
> `download-upscale` calls `GET /app/scene/flow-media/{project}/{chapter}/{scene}/{orientation}`, decodes the base64 `encodedVideo` response, and saves it as an `.mp4` file.
|
|
222
|
+
|
|
199
223
|
---
|
|
200
224
|
|
|
201
225
|
## Monitoring & Status
|
|
@@ -205,6 +229,7 @@ Uses sceneA image → sceneB image as start/end frames. Both must have successfu
|
|
|
205
229
|
| `workflow-status --project X --chapter Y` | Full snapshot: scenes + requests + assets (best for agents) |
|
|
206
230
|
| `scene-status --project X --chapter Y` | Quick image/video status per scene |
|
|
207
231
|
| `requests --project X --limit 10` | Check recent generation jobs |
|
|
232
|
+
| `request-status --id <requestId>` | Check a specific job by request ID (with asset URL) |
|
|
208
233
|
| `failed-requests --project X --chapter Y` | Debug why gen failed |
|
|
209
234
|
| `wait-images --project X --chapter Y --require-success` | Block until all images done |
|
|
210
235
|
| `wait-videos --project X --chapter Y --require-success` | Block until all videos done |
|
|
@@ -217,7 +242,7 @@ Uses sceneA image → sceneB image as start/end frames. Both must have successfu
|
|
|
217
242
|
|
|
218
243
|
1. Verify auth before any command (`veogent status`).
|
|
219
244
|
2. Wait for character readiness (`allReady`) before requesting images.
|
|
220
|
-
3.
|
|
245
|
+
3. **Polling vs Blocking:** For true asynchronous workflows, trigger jobs *without* `--wait`, capture the `requestId`, and poll `request-status --id <requestId>`. Only use `--wait` if you are okay with the CLI locking the process for 5-10 minutes.
|
|
221
246
|
4. Use `workflow-status` as the main status view.
|
|
222
247
|
5. Respect queue limits (max 5 concurrent). `queue-status` to check.
|
|
223
248
|
6. **QA image BEFORE video** — bad image = bad video. Each video gen costs 8-10 min.
|
|
@@ -359,8 +384,9 @@ veogent request --type GENERATE_VIDEO --project X --chapter Y --scene Z \
|
|
|
359
384
|
|
|
360
385
|
| Command | Description | Key Options |
|
|
361
386
|
|---------|-------------|-------------|
|
|
362
|
-
| `request` | Single generation job | `--type
|
|
387
|
+
| `request` | Single generation job | `--type` (GENERATE_IMAGES, GENERATE_VIDEO, UPSCALE_VIDEO), `--project`, `--chapter`, `--scene`, `--orientation`, `--speed`, `--endscene`, `--resolution` (upscale), `--wait` |
|
|
363
388
|
| `batch-request` | Batch generation | `--type`, `--project`, `--chapter`, `--all`/`--scenes`, `--orientation`, `--speed`, `--wait` |
|
|
389
|
+
| `download-upscale` | Download 4K upscaled video as .mp4 | `--project`, `--chapter`, `--scene`, `--orientation`, `--out` |
|
|
364
390
|
|
|
365
391
|
### Monitoring Commands
|
|
366
392
|
|
|
@@ -369,6 +395,7 @@ veogent request --type GENERATE_VIDEO --project X --chapter Y --scene Z \
|
|
|
369
395
|
| `workflow-status` | Full snapshot (best for agents) | `--project`, `--chapter` |
|
|
370
396
|
| `scene-status` | Per-scene image/video status | `--project`, `--chapter` |
|
|
371
397
|
| `requests` | List generation jobs | `--project`, `--chapter`, `--status`, `--limit` |
|
|
398
|
+
| `request-status` | Check a specific job by ID (with asset URL) | `--id` |
|
|
372
399
|
| `failed-requests` | Failed jobs only | `--project`, `--chapter` |
|
|
373
400
|
| `wait-images` | Poll until images done | `--project`, `--chapter`, `--require-success` |
|
|
374
401
|
| `wait-videos` | Poll until videos done | `--project`, `--chapter`, `--require-success` |
|