@cueframe/kernel 0.1.2 → 0.1.4
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/_members/authoring/agent/errors.d.ts +8 -0
- package/dist/_members/authoring/index.d.ts +1 -1
- package/dist/_members/authoring/motion/materializeMotionPresetOps.d.ts +4 -0
- package/dist/_members/authoring/prompts/index.d.ts +0 -1
- package/dist/_members/authoring/types.d.ts +1 -1
- package/dist/_members/cloud-import/CloudImportService.d.ts +3 -4
- package/dist/_members/cloud-import/ImportProvider.d.ts +3 -7
- package/dist/_members/cloud-import/cloudConfig.d.ts +0 -6
- package/dist/_members/cloud-import/index.d.ts +2 -4
- package/dist/_members/composition/graphics-plan/schemas.d.ts +20 -20
- package/dist/_members/composition/primitive-catalog/projection.d.ts +2 -1
- package/dist/_members/composition/projection/behind-readiness.d.ts +4 -2
- package/dist/_members/composition/validators/brandKit.d.ts +54 -94
- package/dist/_members/composition/validators/composePlan.d.ts +52 -52
- package/dist/_members/composition/validators/composition.d.ts +213 -253
- package/dist/_members/composition/validators/font.d.ts +2 -2
- package/dist/_members/composition/validators/index.d.ts +1 -0
- package/dist/_members/composition/validators/opaqueId.d.ts +13 -0
- package/dist/_members/composition/validators/project.d.ts +11 -15
- package/dist/_members/composition/validators/render.d.ts +372 -534
- package/dist/_members/composition/validators/session.d.ts +19 -39
- package/dist/_members/composition/validators/webhook.d.ts +8 -16
- package/dist/_members/composition-ops/index.d.ts +192 -228
- package/dist/_members/director/ai-sdk/messages.d.ts +2 -2
- package/dist/_members/director/domain/chat.d.ts +4 -4
- package/dist/_members/director/testing/contract.d.ts +1 -1
- package/dist/_members/errors/registry.d.ts +115 -1
- package/dist/_members/mcp/adapter.d.ts +19 -0
- package/dist/_members/mcp/core.d.ts +1 -1
- package/dist/_members/mcp/curation.d.ts +4 -0
- package/dist/_members/mcp/generated/harness.d.ts +1 -1
- package/dist/_members/mcp/generated/operations.d.ts +12 -0
- package/dist/_members/mcp/wait.d.ts +1 -1
- package/dist/_members/media-model/api.d.ts +53 -109
- package/dist/_members/media-model/generation.d.ts +2 -2
- package/dist/_members/media-model/index.d.ts +1 -0
- package/dist/_members/media-model/opaqueId.d.ts +10 -0
- package/dist/_members/render-harness/localRender.d.ts +3 -0
- package/dist/_members/render-harness/localRender.d.ts.map +1 -1
- package/dist/_members/render-harness/remotion-runtime.d.ts +53 -0
- package/dist/authoring/build-tools.js +6 -6
- package/dist/authoring/context.js +4 -4
- package/dist/authoring/prompts.js +1 -5
- package/dist/authoring/tools.js +5 -5
- package/dist/authoring.js +40 -27
- package/dist/chunk-2SNY75AR.js +498 -0
- package/dist/{chunk-XQ72DZKJ.js → chunk-7TQCR7AB.js} +1 -1
- package/dist/{chunk-QETYXKQQ.js → chunk-7V3F5HO4.js} +97 -14
- package/dist/{chunk-BZZTVOGG.js → chunk-D2EGO543.js} +5 -5
- package/dist/{chunk-ZPLJ24OV.js → chunk-D6S3ZKIY.js} +1 -1
- package/dist/{chunk-K2IUBCND.js → chunk-HFC3MKXA.js} +0 -51
- package/dist/{chunk-ICSZF37W.js → chunk-JRIPQ7DN.js} +1 -1
- package/dist/{chunk-TFGKUWHY.js → chunk-JTVFIN6H.js} +15 -19
- package/dist/{chunk-DCVJWGIA.js → chunk-JY26PIRP.js} +2 -2
- package/dist/{chunk-DWLNPNC4.js → chunk-LSP4HN5N.js} +1 -1
- package/dist/{chunk-AO744WIK.js → chunk-PJ4R4N4Q.js} +123 -38
- package/dist/{chunk-VFMW3JUY.js → chunk-QSDFTYKV.js} +1 -1
- package/dist/{chunk-LLUW26BS.js → chunk-R5BMJ2NX.js} +38 -2
- package/dist/{chunk-W3SIWT7J.js → chunk-RQ2G4DXI.js} +406 -174
- package/dist/{chunk-VHF66LCQ.js → chunk-RXCEPCAQ.js} +102 -41
- package/dist/{chunk-LJ5W4ZBU.js → chunk-TLVPDT4R.js} +1 -1
- package/dist/{chunk-PIURX6IZ.js → chunk-WTT3GGCA.js} +9 -4
- package/dist/{chunk-CAJQ7H5A.js → chunk-YE3F4LNJ.js} +17 -17
- package/dist/{chunk-TD347SSX.js → chunk-YXEZ75MB.js} +31 -20
- package/dist/{chunk-TPA6PYN2.js → chunk-ZBRPF6GV.js} +25 -10
- package/dist/cloud-import.js +20 -116
- package/dist/compose/renderer.js +17 -17
- package/dist/compose.js +18 -18
- package/dist/composition/graphics-plan.js +1 -1
- package/dist/composition/ops.js +3 -3
- package/dist/composition/primitive-catalog.js +1 -1
- package/dist/composition/projection.js +2 -2
- package/dist/composition/validators.js +4 -2
- package/dist/composition-ops.js +6 -6
- package/dist/composition.js +6 -4
- package/dist/{context-JLLU3MYD.js → context-XWNT6QZH.js} +4 -4
- package/dist/core/render.js +3 -3
- package/dist/core/select.js +2 -2
- package/dist/core.js +3 -3
- package/dist/director/ai-sdk.js +3 -3
- package/dist/director/domain.js +2 -2
- package/dist/director.js +3 -3
- package/dist/errors.js +1 -1
- package/dist/mcp/adapter.js +59 -22
- package/dist/mcp/core.js +1 -1
- package/dist/mcp/curation.js +5 -1
- package/dist/mcp/server.js +4 -4
- package/dist/mcp.js +4 -4
- package/dist/media-model/media-kind.js +98 -9
- package/dist/media-model/testing.js +6 -6
- package/dist/media-model.js +83 -77
- package/dist/nle-export.js +18 -18
- package/dist/primitives/backgrounds.js +2 -2
- package/dist/primitives/captions.js +3 -3
- package/dist/primitives/effects.js +2 -2
- package/dist/primitives/hero-text.js +2 -2
- package/dist/primitives/layouts.js +2 -2
- package/dist/primitives/lib/index.js +12 -12
- package/dist/primitives/lib.js +12 -12
- package/dist/primitives/scenes.js +2 -2
- package/dist/primitives/text.js +2 -2
- package/dist/primitives/ui-blocks.js +2 -2
- package/dist/primitives.js +19 -19
- package/dist/render-harness.js +4 -2
- package/package.json +13 -37
- package/dist/_members/authoring/prompts/designReviewerPrompt.d.ts +0 -2
- package/dist/_members/cloud-import/MediaItemPreprocessor.d.ts +0 -18
- package/dist/_members/cloud-import/multipartUpload.d.ts +0 -12
- package/dist/_members/convex-api/api.d.ts +0 -2
- package/dist/_members/convex-api/dataModel.d.ts +0 -4
- package/dist/chunk-6IU2UQI5.js +0 -107
- package/dist/chunk-EP2Y6M2J.js +0 -64
- package/dist/chunk-WZH57M53.js +0 -494
- package/dist/cloud-import/multipart.d.ts +0 -1
- package/dist/cloud-import/multipart.js +0 -8
- package/dist/convex-api/dataModel.d.ts +0 -1
- package/dist/convex-api/dataModel.js +0 -0
- package/dist/convex-api.d.ts +0 -1
- package/dist/convex-api.js +0 -8
- package/dist/{chunk-RP4SXXLJ.js → chunk-3PM6VICZ.js} +3 -3
- package/dist/{chunk-UQSOS726.js → chunk-6ABIXGLO.js} +4 -4
- package/dist/{chunk-SAMQUUO5.js → chunk-BIBYZJL3.js} +3 -3
- package/dist/{chunk-GMD33ZD7.js → chunk-O7GNE4BQ.js} +3 -3
- package/dist/{chunk-BKHGL4MB.js → chunk-THJAY7QS.js} +4 -4
- package/dist/{chunk-DYZE7JZA.js → chunk-TMIBBD5E.js} +3 -3
- package/dist/{chunk-G5BFI32U.js → chunk-XATRRDVG.js} +3 -3
|
@@ -3,6 +3,10 @@ import {
|
|
|
3
3
|
buildEasedZooms,
|
|
4
4
|
buildPannedCenters
|
|
5
5
|
} from "./chunk-QH3YI3ND.js";
|
|
6
|
+
import {
|
|
7
|
+
flattenCompoundClips,
|
|
8
|
+
hasCompoundClips
|
|
9
|
+
} from "./chunk-23HFEKV7.js";
|
|
6
10
|
import {
|
|
7
11
|
DOMINANCE_WEIGHTS,
|
|
8
12
|
ENTER_SEC,
|
|
@@ -20,11 +24,7 @@ import {
|
|
|
20
24
|
scoreAndRank,
|
|
21
25
|
segmentShots,
|
|
22
26
|
stabilizeSelectionHysteresis
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import {
|
|
25
|
-
flattenCompoundClips,
|
|
26
|
-
hasCompoundClips
|
|
27
|
-
} from "./chunk-23HFEKV7.js";
|
|
27
|
+
} from "./chunk-7TQCR7AB.js";
|
|
28
28
|
import {
|
|
29
29
|
compositionHasVo,
|
|
30
30
|
roleDefaultGainDb
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
import {
|
|
37
37
|
CueframeError,
|
|
38
38
|
encodeError
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-R5BMJ2NX.js";
|
|
40
40
|
|
|
41
41
|
// ../execution/core/src/render/emphasis.ts
|
|
42
42
|
function buildEmphasisSet(emphasisWords) {
|
|
@@ -178,6 +178,9 @@ function resolveBookendTimeline(brandKit, bodyFrames, fps) {
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
// ../execution/core/src/render/compositionRender.ts
|
|
181
|
+
function renderInputError(code, message, locator) {
|
|
182
|
+
return new CueframeError(code, message, void 0, locator);
|
|
183
|
+
}
|
|
181
184
|
function projectClipEffects(clip, renderClipId) {
|
|
182
185
|
const effects = clip.effects;
|
|
183
186
|
if (!effects || effects.length === 0) return [];
|
|
@@ -217,53 +220,81 @@ function compositionFormatDimensions(format) {
|
|
|
217
220
|
}
|
|
218
221
|
function validateComposition(raw) {
|
|
219
222
|
if (!raw || typeof raw !== "object") {
|
|
220
|
-
throw
|
|
223
|
+
throw renderInputError("invalid_composition", "composition: expected object, got " + typeof raw, {
|
|
224
|
+
compositionPath: "composition"
|
|
225
|
+
});
|
|
221
226
|
}
|
|
222
227
|
const obj = raw;
|
|
223
228
|
if (obj.v !== 1) {
|
|
224
|
-
throw
|
|
229
|
+
throw renderInputError("invalid_composition", "composition.v: expected literal 1", {
|
|
230
|
+
compositionPath: "composition.v"
|
|
231
|
+
});
|
|
225
232
|
}
|
|
226
233
|
const fmt = obj.format;
|
|
227
234
|
if (!fmt || typeof fmt.aspectRatio !== "string") {
|
|
228
|
-
throw
|
|
235
|
+
throw renderInputError("invalid_composition", "composition.format.aspectRatio: required string", {
|
|
236
|
+
compositionPath: "composition.format.aspectRatio"
|
|
237
|
+
});
|
|
229
238
|
}
|
|
230
239
|
if (!Array.isArray(obj.tracks)) {
|
|
231
|
-
throw
|
|
240
|
+
throw renderInputError("invalid_composition", "composition.tracks: expected array", {
|
|
241
|
+
compositionPath: "composition.tracks"
|
|
242
|
+
});
|
|
232
243
|
}
|
|
233
244
|
for (let i = 0; i < obj.tracks.length; i++) {
|
|
234
245
|
const t = obj.tracks[i];
|
|
235
246
|
if (!t || typeof t !== "object") {
|
|
236
|
-
throw
|
|
247
|
+
throw renderInputError("invalid_composition", `composition.tracks[${i}]: expected object`, {
|
|
248
|
+
compositionPath: `composition.tracks[${i}]`
|
|
249
|
+
});
|
|
237
250
|
}
|
|
238
251
|
if (typeof t.id !== "string") {
|
|
239
|
-
throw
|
|
252
|
+
throw renderInputError("invalid_composition", `composition.tracks[${i}].id: expected string`, {
|
|
253
|
+
compositionPath: `composition.tracks[${i}].id`
|
|
254
|
+
});
|
|
240
255
|
}
|
|
241
256
|
if (!["video", "audio", "image", "overlay", "effect"].includes(t.kind)) {
|
|
242
|
-
throw
|
|
257
|
+
throw renderInputError("invalid_composition", `composition.tracks[${i}].kind: invalid value`, {
|
|
258
|
+
compositionPath: `composition.tracks[${i}].kind`,
|
|
259
|
+
...typeof t.id === "string" ? { trackId: t.id } : {}
|
|
260
|
+
});
|
|
243
261
|
}
|
|
244
262
|
if (!Array.isArray(t.contents)) {
|
|
245
|
-
throw
|
|
263
|
+
throw renderInputError("invalid_composition", `composition.tracks[${i}].contents: expected array`, {
|
|
264
|
+
compositionPath: `composition.tracks[${i}].contents`,
|
|
265
|
+
trackId: t.id
|
|
266
|
+
});
|
|
246
267
|
}
|
|
247
268
|
}
|
|
248
269
|
if (obj.markers !== void 0 && !Array.isArray(obj.markers)) {
|
|
249
|
-
throw
|
|
270
|
+
throw renderInputError("invalid_composition", "composition.markers: expected array when present", {
|
|
271
|
+
compositionPath: "composition.markers"
|
|
272
|
+
});
|
|
250
273
|
}
|
|
251
274
|
if (obj.captions !== void 0) {
|
|
252
275
|
const c = obj.captions;
|
|
253
276
|
if (!c || typeof c !== "object") {
|
|
254
|
-
throw
|
|
277
|
+
throw renderInputError("invalid_composition", "composition.captions: expected object when present", {
|
|
278
|
+
compositionPath: "composition.captions"
|
|
279
|
+
});
|
|
255
280
|
}
|
|
256
281
|
if (!Array.isArray(c.segments)) {
|
|
257
|
-
throw
|
|
282
|
+
throw renderInputError("invalid_composition", "composition.captions.segments: expected array", {
|
|
283
|
+
compositionPath: "composition.captions.segments"
|
|
284
|
+
});
|
|
258
285
|
}
|
|
259
286
|
if (c.style !== void 0 && (typeof c.style !== "object" || c.style === null)) {
|
|
260
|
-
throw
|
|
287
|
+
throw renderInputError("invalid_composition", "composition.captions.style: expected object when present", {
|
|
288
|
+
compositionPath: "composition.captions.style"
|
|
289
|
+
});
|
|
261
290
|
}
|
|
262
291
|
if (c.style !== void 0) {
|
|
263
292
|
const fs = c.style.fontSize;
|
|
264
293
|
if (fs !== void 0 && (typeof fs !== "number" || fs < 1 || fs > 15)) {
|
|
265
|
-
throw
|
|
266
|
-
|
|
294
|
+
throw renderInputError(
|
|
295
|
+
"invalid_composition",
|
|
296
|
+
`composition.captions.style.fontSize: PERCENT of composition height (1-15, default 5) \u2014 got ${String(fs)}. px values are not accepted; a px-intent value renders giant band-overflowing captions. Re-author the style with a percent value.`,
|
|
297
|
+
{ compositionPath: "composition.captions.style.fontSize" }
|
|
267
298
|
);
|
|
268
299
|
}
|
|
269
300
|
}
|
|
@@ -299,11 +330,13 @@ function overlayTransitionFields(c, fps) {
|
|
|
299
330
|
function rendersNoFrames(c) {
|
|
300
331
|
return !(c.duration > 0);
|
|
301
332
|
}
|
|
302
|
-
function resolveSrcUrl(mediaId, srcUrls) {
|
|
333
|
+
function resolveSrcUrl(mediaId, srcUrls, locator) {
|
|
303
334
|
const url = srcUrls[mediaId];
|
|
304
335
|
if (!url) {
|
|
305
|
-
throw
|
|
306
|
-
|
|
336
|
+
throw renderInputError(
|
|
337
|
+
"source_media_not_found",
|
|
338
|
+
`Composition references mediaId '${mediaId}' but no presigned URL was supplied. Pre-sign every unique mediaId before calling compositionToRenderInput.`,
|
|
339
|
+
{ ...locator, mediaId }
|
|
307
340
|
);
|
|
308
341
|
}
|
|
309
342
|
return url;
|
|
@@ -329,15 +362,24 @@ function projectMediaTrack(track, fps, srcUrls, trajectoryUrls, coViewUrls, traj
|
|
|
329
362
|
const c = track.contents[i];
|
|
330
363
|
if (!("source" in c) || !c.source) continue;
|
|
331
364
|
if (c.source.kind !== "media") {
|
|
332
|
-
throw
|
|
333
|
-
|
|
365
|
+
throw renderInputError(
|
|
366
|
+
"clip_source_track_mismatch",
|
|
367
|
+
`composition.tracks[${track.id}].contents[${i}]: kind=${c.source.kind} is invalid on a ${track.kind} track (expected 'media')`,
|
|
368
|
+
{ trackId: track.id, clipId: c.id, compositionPath: `composition.tracks[${track.id}].contents[${i}].source` }
|
|
334
369
|
);
|
|
335
370
|
}
|
|
336
371
|
if (rendersNoFrames(c)) continue;
|
|
337
|
-
const src = resolveSrcUrl(c.source.mediaId, srcUrls
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
372
|
+
const src = resolveSrcUrl(c.source.mediaId, srcUrls, {
|
|
373
|
+
trackId: track.id,
|
|
374
|
+
clipId: c.id,
|
|
375
|
+
compositionPath: `composition.tracks[${track.id}].contents[${i}].source.mediaId`
|
|
376
|
+
});
|
|
377
|
+
const packedUrl = coViewUrls?.[c.id] ?? coViewUrls?.[c.source.mediaId];
|
|
378
|
+
if (packedUrl !== void 0 && c.region !== void 0 && !(c.region.x === 0 && c.region.y === 0 && c.region.w === 1 && c.region.h === 1)) {
|
|
379
|
+
throw renderInputError(
|
|
380
|
+
"invalid_composition",
|
|
381
|
+
`composition.tracks[${track.id}].contents[${i}] (clip ${c.id}): a co-view clip (captions-behind-subject) cannot also carry a sub-frame region \u2014 the co-view render path does not honor region. Use one or the other.`,
|
|
382
|
+
{ trackId: track.id, clipId: c.id, compositionPath: `composition.tracks[${track.id}].contents[${i}].region` }
|
|
341
383
|
);
|
|
342
384
|
}
|
|
343
385
|
if (track.kind === "audio") {
|
|
@@ -412,7 +454,7 @@ function projectMediaTrack(track, fps, srcUrls, trajectoryUrls, coViewUrls, traj
|
|
|
412
454
|
} : {},
|
|
413
455
|
...trajectoryUrls?.[c.id] !== void 0 ? { cropTrajectoryUrl: trajectoryUrls[c.id] } : {},
|
|
414
456
|
...trajectories?.[c.id] !== void 0 ? { cropTrajectory: trajectories[c.id] } : {},
|
|
415
|
-
...
|
|
457
|
+
...packedUrl !== void 0 ? { packedUrl } : {}
|
|
416
458
|
});
|
|
417
459
|
}
|
|
418
460
|
if (firstEmittedSubId !== void 0) {
|
|
@@ -444,12 +486,18 @@ function projectImageTrack(track, fps, srcUrls) {
|
|
|
444
486
|
const c = track.contents[i];
|
|
445
487
|
if (!("source" in c) || !c.source) continue;
|
|
446
488
|
if (c.source.kind !== "media") {
|
|
447
|
-
throw
|
|
448
|
-
|
|
489
|
+
throw renderInputError(
|
|
490
|
+
"clip_source_track_mismatch",
|
|
491
|
+
`composition.tracks[${track.id}].contents[${i}]: kind=${c.source.kind} is invalid on an image track (expected 'media')`,
|
|
492
|
+
{ trackId: track.id, clipId: c.id, compositionPath: `composition.tracks[${track.id}].contents[${i}].source` }
|
|
449
493
|
);
|
|
450
494
|
}
|
|
451
495
|
if (rendersNoFrames(c)) continue;
|
|
452
|
-
const src = resolveSrcUrl(c.source.mediaId, srcUrls
|
|
496
|
+
const src = resolveSrcUrl(c.source.mediaId, srcUrls, {
|
|
497
|
+
trackId: track.id,
|
|
498
|
+
clipId: c.id,
|
|
499
|
+
compositionPath: `composition.tracks[${track.id}].contents[${i}].source.mediaId`
|
|
500
|
+
});
|
|
453
501
|
const { startFrame: timelineStartFrames, durationInFrames } = timelineSpanFrames(
|
|
454
502
|
c.startTime,
|
|
455
503
|
c.startTime + c.duration,
|
|
@@ -501,8 +549,15 @@ function projectOverlayTrack(track, fps, alphaUrls = {}, jsSourceByClipId = {})
|
|
|
501
549
|
if (durationInFrames2 === 0) continue;
|
|
502
550
|
const src = alphaUrls[c.id];
|
|
503
551
|
if (!src) {
|
|
504
|
-
throw
|
|
505
|
-
|
|
552
|
+
throw renderInputError(
|
|
553
|
+
"variant_not_baked",
|
|
554
|
+
`composition.tracks[${track.id}].contents[${i}]: alpha-layer clip ${c.id} has no baked alpha (alphaUrls[${c.id}] missing) \u2014 bake before render`,
|
|
555
|
+
{
|
|
556
|
+
trackId: track.id,
|
|
557
|
+
clipId: c.id,
|
|
558
|
+
componentId: c.source.componentId,
|
|
559
|
+
compositionPath: `composition.tracks[${track.id}].contents[${i}].source`
|
|
560
|
+
}
|
|
506
561
|
);
|
|
507
562
|
}
|
|
508
563
|
overlays.push({
|
|
@@ -544,8 +599,10 @@ function projectOverlayTrack(track, fps, alphaUrls = {}, jsSourceByClipId = {})
|
|
|
544
599
|
continue;
|
|
545
600
|
}
|
|
546
601
|
if (c.source.kind !== "overlay") {
|
|
547
|
-
throw
|
|
548
|
-
|
|
602
|
+
throw renderInputError(
|
|
603
|
+
"clip_source_track_mismatch",
|
|
604
|
+
`composition.tracks[${track.id}].contents[${i}]: kind=${c.source.kind} is invalid on an overlay track (expected 'overlay', 'alpha-layer', or 'card')`,
|
|
605
|
+
{ trackId: track.id, clipId: c.id, compositionPath: `composition.tracks[${track.id}].contents[${i}].source` }
|
|
549
606
|
);
|
|
550
607
|
}
|
|
551
608
|
const { startFrame, durationInFrames } = timelineSpanFrames(
|
|
@@ -559,8 +616,10 @@ function projectOverlayTrack(track, fps, alphaUrls = {}, jsSourceByClipId = {})
|
|
|
559
616
|
const fresh = jsSourceByClipId[c.id];
|
|
560
617
|
const sc = typeof fresh === "string" && fresh.length > 0 ? fresh : overlayParams.sourceCode;
|
|
561
618
|
if (typeof sc !== "string" || sc.length === 0) {
|
|
562
|
-
throw
|
|
563
|
-
|
|
619
|
+
throw renderInputError(
|
|
620
|
+
"custom_missing_sourcecode",
|
|
621
|
+
`composition.tracks[${track.id}].contents[${i}].source: custom overlay has no sourceCode (no fresh jsSource for clip '${c.id}' and no inline params.sourceCode) \u2014 mirror code 'custom_missing_sourcecode'`,
|
|
622
|
+
{ trackId: track.id, clipId: c.id, compositionPath: `composition.tracks[${track.id}].contents[${i}].source` }
|
|
564
623
|
);
|
|
565
624
|
}
|
|
566
625
|
const { componentId: _cid, sourceCode: _sc, ...props } = overlayParams;
|
|
@@ -591,8 +650,10 @@ function projectEffectTrack(track, fps) {
|
|
|
591
650
|
const c = track.contents[i];
|
|
592
651
|
if (!("source" in c) || !c.source) continue;
|
|
593
652
|
if (c.source.kind !== "effect") {
|
|
594
|
-
throw
|
|
595
|
-
|
|
653
|
+
throw renderInputError(
|
|
654
|
+
"clip_source_track_mismatch",
|
|
655
|
+
`composition.tracks[${track.id}].contents[${i}]: kind=${c.source.kind} is invalid on an effect track (expected 'effect')`,
|
|
656
|
+
{ trackId: track.id, clipId: c.id, compositionPath: `composition.tracks[${track.id}].contents[${i}].source` }
|
|
596
657
|
);
|
|
597
658
|
}
|
|
598
659
|
const { startFrame, durationInFrames } = timelineSpanFrames(
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
CueframeError,
|
|
8
8
|
encodeError
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-R5BMJ2NX.js";
|
|
10
10
|
|
|
11
11
|
// ../composition/src/projection/cardTokens.ts
|
|
12
12
|
var CARD_MOTION_VAR_NAMES = [
|
|
@@ -154,7 +154,10 @@ function overlapsMs(aStartSec, aDurationSec, bStartSec, bDurationSec) {
|
|
|
154
154
|
}
|
|
155
155
|
function tracksOf(composition) {
|
|
156
156
|
const tracks = composition?.tracks;
|
|
157
|
-
|
|
157
|
+
if (!Array.isArray(tracks)) return [];
|
|
158
|
+
return tracks.filter(
|
|
159
|
+
(track) => track.enabled !== false
|
|
160
|
+
);
|
|
158
161
|
}
|
|
159
162
|
function clipsOf(track) {
|
|
160
163
|
const contents = track.contents;
|
|
@@ -210,7 +213,7 @@ async function behindReadinessForTarget(target, mattes) {
|
|
|
210
213
|
if (!target) return { state: "no-clip" };
|
|
211
214
|
const key = await matteIntentKey({ ...target.window, subjectClass: "person" });
|
|
212
215
|
const entry = mattes?.[key];
|
|
213
|
-
if (!entry?.geometryR2Key) return { state: "no-matte", target };
|
|
216
|
+
if (!entry?.geometryUrl && !entry?.geometryR2Key) return { state: "no-matte", target };
|
|
214
217
|
const presenceFraction = entry.presenceFraction ?? 0;
|
|
215
218
|
if (presenceFraction < MIN_PRESENCE_FOR_BEHIND) {
|
|
216
219
|
return { state: "no-subject", target, presenceFraction };
|
|
@@ -237,7 +240,9 @@ function matteWindowsByMediaId(composition, behindWindows) {
|
|
|
237
240
|
const startSec = typeof trim?.start === "number" ? trim.start : 0;
|
|
238
241
|
const endSec = typeof trim?.end === "number" ? trim.end : startSec + clip.duration;
|
|
239
242
|
if (endSec <= startSec) continue;
|
|
240
|
-
|
|
243
|
+
const windows = out.get(mediaId) ?? [];
|
|
244
|
+
windows.push({ clipId: clip.id, startSec, endSec });
|
|
245
|
+
out.set(mediaId, windows);
|
|
241
246
|
}
|
|
242
247
|
}
|
|
243
248
|
return out;
|
|
@@ -1,41 +1,41 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isContrastCritical
|
|
3
3
|
} from "./chunk-YLDMAZZE.js";
|
|
4
|
-
import {
|
|
5
|
-
catalog as catalog6
|
|
6
|
-
} from "./chunk-BKHGL4MB.js";
|
|
7
|
-
import {
|
|
8
|
-
catalog as catalog2
|
|
9
|
-
} from "./chunk-GMD33ZD7.js";
|
|
10
|
-
import {
|
|
11
|
-
catalog as catalog8
|
|
12
|
-
} from "./chunk-SAMQUUO5.js";
|
|
13
|
-
import {
|
|
14
|
-
catalog as catalog4
|
|
15
|
-
} from "./chunk-RP4SXXLJ.js";
|
|
16
4
|
import {
|
|
17
5
|
catalog as catalog7
|
|
18
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-TMIBBD5E.js";
|
|
19
7
|
import {
|
|
20
8
|
catalog
|
|
21
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6ABIXGLO.js";
|
|
22
10
|
import {
|
|
23
11
|
catalog as catalog3
|
|
24
12
|
} from "./chunk-AWT3P5ZN.js";
|
|
13
|
+
import {
|
|
14
|
+
catalog as catalog6
|
|
15
|
+
} from "./chunk-THJAY7QS.js";
|
|
25
16
|
import {
|
|
26
17
|
catalog as catalog5
|
|
27
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-XATRRDVG.js";
|
|
19
|
+
import {
|
|
20
|
+
catalog as catalog2
|
|
21
|
+
} from "./chunk-O7GNE4BQ.js";
|
|
22
|
+
import {
|
|
23
|
+
catalog as catalog8
|
|
24
|
+
} from "./chunk-BIBYZJL3.js";
|
|
25
|
+
import {
|
|
26
|
+
catalog as catalog4
|
|
27
|
+
} from "./chunk-3PM6VICZ.js";
|
|
28
28
|
import {
|
|
29
29
|
getPrimitiveSubtextParam,
|
|
30
30
|
getPrimitiveTextParam
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-JY26PIRP.js";
|
|
32
32
|
import {
|
|
33
33
|
NEUTRAL_RAMP
|
|
34
34
|
} from "./chunk-JF4JJAFP.js";
|
|
35
35
|
import {
|
|
36
36
|
CueframeError,
|
|
37
37
|
encodeError
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-R5BMJ2NX.js";
|
|
39
39
|
|
|
40
40
|
// ../execution/compose/src/primitiveRegistry.ts
|
|
41
41
|
var allCatalogs = [
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
waitForJob
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-7V3F5HO4.js";
|
|
4
|
+
import {
|
|
5
|
+
CURATED_TOOLS
|
|
6
|
+
} from "./chunk-PJ4R4N4Q.js";
|
|
4
7
|
import {
|
|
5
8
|
GENERATED_OPERATIONS,
|
|
6
9
|
apiErrorFrom,
|
|
@@ -17,10 +20,7 @@ import {
|
|
|
17
20
|
sniffImageMediaType,
|
|
18
21
|
text,
|
|
19
22
|
withMedia
|
|
20
|
-
} from "./chunk-
|
|
21
|
-
import {
|
|
22
|
-
CURATED_TOOLS
|
|
23
|
-
} from "./chunk-AO744WIK.js";
|
|
23
|
+
} from "./chunk-RQ2G4DXI.js";
|
|
24
24
|
|
|
25
25
|
// ../mcp/src/prompts.ts
|
|
26
26
|
var skillListCache = null;
|
|
@@ -91,17 +91,17 @@ CLIPPING (find the best short-form moments in a long video): \`suggest_briefs\`
|
|
|
91
91
|
|
|
92
92
|
Every expensive step has a cheap, inspectable check \u2014 prefer reading a value over rendering and eyeballing:
|
|
93
93
|
- Framing & timing are data: \`get_media_context\` BEFORE you compose.
|
|
94
|
-
- Evidence beats guessing: \`preview_frame\` (whole-composition stills), \`preview_component\` (ONE graphic
|
|
94
|
+
- Evidence beats guessing: \`preview_frame\` (whole-composition stills), \`preview_component\` (ONE authored graphic: \`executionMode:"live"\` returns a PNG image; \`executionMode:"baked"\` returns a transparent VP9 motion clip \u2014 exactly the lane production composites), \`preview_clip\` (a fromSec\u2192toSec window as a watchable MP4, max 60s, capture-priced \u2014 judge a cut or transition at full fidelity WITHOUT paying for a full render). These are STATELESS: nothing to open, warm, or close; concurrent previews do not contend. \`preview_frame\` defaults to the PERSISTED composition and echoes \`previewed.{source, compositionId, etag}\` \u2014 what you saw is what create_render encodes.
|
|
95
95
|
- Quality is a number: \`score_composition\` returns scores + critique + a checkpointId; the compose result carries the winner's composite. **score vs consult**: score answers "how good IS this" (grounded numbers); \`consult\` answers "what SHOULD I change" (advice + an adoptable fix via \`select_candidate\`).
|
|
96
96
|
|
|
97
97
|
## Async model
|
|
98
98
|
|
|
99
99
|
Every long job is either polled or pushed \u2014 never guessed:
|
|
100
|
-
- \`wait_job\` kinds: \`render\`, \`compose\`, \`suggestions\`, \`verify\` (score jobs), \`preview\` (component
|
|
100
|
+
- \`wait_job\` kinds: \`media\` (imports/generation), \`render\`, \`compose\`, \`suggestions\`, \`verify\` (score jobs), \`preview_frame\` (composition stills), \`preview\` (component image-or-motion previews), \`brand_kit_extract\`, \`consult\`. It blocks up to its window and returns a CONTINUATION when still running \u2014 re-call it.
|
|
101
101
|
- Webhooks (\`create_webhook\`): ONE terminal event per kind with status INSIDE the payload \u2014 \`render.completed\`, \`compose.completed\`, \`media.completed\`, \`suggest.completed\` \u2014 plus \`checkpoint.ready\` (a held compose paused for review). Read \`cueframe://webhook-events\` for the full contract before building a receiver.
|
|
102
102
|
- Presigned URLs (stills, clips, render outputs) expire \u2014 render outputs last ~7 days (refresh via the render's refresh-url op); preview stills/clips ~1 hour. Re-read for a fresh link instead of caching one.
|
|
103
103
|
|
|
104
|
-
CUSTOM GRAPHICS \u2014 author or FORK: \`create_component\` (tsxSource) from scratch, or \`get_component_source\` on a built-in primitive (e.g. \`cinematic-title\`) to fork its editable module. Iterate author\u2192preview\u2192fix with \`preview_component\` (202 + jobId; \`wait_job(kind:"preview")\` returns
|
|
104
|
+
CUSTOM GRAPHICS \u2014 author or FORK: \`create_component\` (tsxSource) from scratch, or \`get_component_source\` on a built-in primitive (e.g. \`cinematic-title\`) to fork its editable module. Iterate author\u2192preview\u2192fix with \`preview_component\` (202 + jobId; \`wait_job(kind:"preview")\` returns a PNG image for \`executionMode:"live"\` or a VP9 motion URL for \`executionMode:"baked"\`; a compile failure lands on the job's FAILED terminal carrying the sanitized compiler error) \u2192 fix via \`update_component\` \u2192 preview again. Place baked components via \`apply_composition\` as an \`alpha-layer\` clip \u2014 the shared renderer never runs authored source code (it composites the transparent baked video).
|
|
105
105
|
|
|
106
106
|
Cleanup: \`delete_project\` / \`delete_media\` / \`delete_webhook\` / \`delete_composition\`. \`list_projects\` re-orients you in an existing workspace; \`list_media\` (filter by \`source\`/\`tag\`) lists the library.
|
|
107
107
|
|
|
@@ -436,12 +436,16 @@ function registerCuratedTools(server, ex, opts) {
|
|
|
436
436
|
for (const friendly of Object.keys(spec.pathArgs ?? {})) {
|
|
437
437
|
inputSchema[friendly] = z.string().describe(`${friendly} (path).`);
|
|
438
438
|
}
|
|
439
|
+
for (const [queryArg, description] of Object.entries(spec.queryArgs ?? {})) {
|
|
440
|
+
inputSchema[queryArg] = z.string().optional().describe(description);
|
|
441
|
+
}
|
|
439
442
|
const bodySchema = bodySchemaFor(op);
|
|
440
443
|
if (bodySchema) inputSchema.body = bodySchema;
|
|
441
444
|
const annotations = { ...op.annotations, ...spec.annotations };
|
|
442
445
|
server.registerTool(spec.name, { title: spec.title ?? titleCase(spec.name), description: spec.description, inputSchema, annotations }, async (args, extra) => timed(opts?.onEvent, spec.name, async (report) => {
|
|
443
446
|
const a = args;
|
|
444
447
|
try {
|
|
448
|
+
const query = Object.keys(spec.queryArgs ?? {}).filter((name) => a[name] !== void 0 && a[name] !== null && a[name] !== "").map((name) => `${encodeURIComponent(name)}=${encodeURIComponent(String(a[name]))}`).join("&");
|
|
445
449
|
return await dispatchOp(ex, op, (p) => a[reverse[p]], a.body, extra, spec.name, async (res) => {
|
|
446
450
|
if (spec.okText) return text(spec.okText(a));
|
|
447
451
|
const json = res.text ? safeParse(res.text) : void 0;
|
|
@@ -454,17 +458,17 @@ function registerCuratedTools(server, ex, opts) {
|
|
|
454
458
|
if (data.length) return withMedia(payload, data.map((d) => ({ data: d, kind })));
|
|
455
459
|
}
|
|
456
460
|
return text(payload);
|
|
457
|
-
});
|
|
461
|
+
}, query || void 0);
|
|
458
462
|
} catch (err) {
|
|
459
463
|
return errText(`${spec.name} failed: ${fmtErr(err)}`);
|
|
460
464
|
}
|
|
461
465
|
}));
|
|
462
466
|
}
|
|
463
467
|
registerWaitJob(server, ex, opts?.waitCapMs, opts?.onEvent);
|
|
464
|
-
registerPreviewCard(server, ex, opts?.onEvent);
|
|
468
|
+
registerPreviewCard(server, ex, opts?.waitCapMs, opts?.onEvent);
|
|
465
469
|
}
|
|
466
|
-
function registerPreviewCard(server, ex, onEvent) {
|
|
467
|
-
const op = opById("
|
|
470
|
+
function registerPreviewCard(server, ex, waitCapMs, onEvent) {
|
|
471
|
+
const op = opById("previewFrameJob");
|
|
468
472
|
server.registerTool(
|
|
469
473
|
"preview_card",
|
|
470
474
|
{
|
|
@@ -508,12 +512,19 @@ function registerPreviewCard(server, ex, onEvent) {
|
|
|
508
512
|
"preview_card",
|
|
509
513
|
async (res) => {
|
|
510
514
|
const json = res.text ? safeParse(res.text) : void 0;
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
-
|
|
515
|
+
const jobId = json?.jobId;
|
|
516
|
+
if (typeof jobId !== "string" || !jobId) {
|
|
517
|
+
return errText("preview_card enqueue returned no jobId");
|
|
518
|
+
}
|
|
519
|
+
const waitMs = Math.min(waitCapMs ?? 3e4, 3e4);
|
|
520
|
+
const done = await waitForJob(ex, "preview_frame", jobId, void 0, Date.now() + waitMs);
|
|
521
|
+
if (!done.ok) return errText(done.text);
|
|
522
|
+
if (done.stillRunning) return text(`${done.text}
|
|
523
|
+
jobId: ${jobId}`);
|
|
524
|
+
const urls = done.mediaUrls ?? [];
|
|
514
525
|
const data = await fetchPreviews(urls, 2);
|
|
515
526
|
report({ preview: { urls: urls.filter(Boolean).length, fetched: data.length } });
|
|
516
|
-
const payload =
|
|
527
|
+
const payload = done.text || `previewed card (${a.aspectRatio ?? "9:16"})`;
|
|
517
528
|
return data.length ? withMedia(payload, data.map((d) => ({ data: d, kind: "image" }))) : text(payload);
|
|
518
529
|
}
|
|
519
530
|
);
|
|
@@ -529,10 +540,10 @@ function registerWaitJob(server, ex, waitCapMs, onEvent) {
|
|
|
529
540
|
{
|
|
530
541
|
title: "Wait for Job",
|
|
531
542
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
532
|
-
description: "Wait for a long-running job and return the resolved result \u2014 a BOUNDED long-poll. Polls
|
|
543
|
+
description: "Wait for a long-running job and return the resolved result \u2014 a BOUNDED long-poll. Polls job status (media import/generation / render / compose / consult / clip-suggestions / verify / preview-frame) and blocks up to the transport window (30s on the hosted transport); if still running, it returns a continuation \u2014 call wait_job again with the same arguments (the job keeps executing server-side). Call this after import_media / generate_media / finalize_upload / import_resource / compose / create_render / consult / suggest_briefs / score_composition / preview_frame / preview_component. For event-driven fan-out, create_webhook delivers the terminal instead.",
|
|
533
544
|
inputSchema: {
|
|
534
|
-
kind: z.enum(["render", "suggestions", "compose", "verify", "preview", "brand_kit_extract", "consult"]).describe("What to wait on:
|
|
535
|
-
id: z.string().describe('kind="render": renderId. kind="compose": composeJobId. kind="consult":
|
|
545
|
+
kind: z.enum(["media", "render", "suggestions", "compose", "verify", "preview_frame", "preview", "brand_kit_extract", "consult"]).describe("What to wait on: media ingest/generation, render, compose, consult, clip-suggestion analysis, or a generic async job (verify / preview_frame / preview / brand-kit extract \u2014 use the enqueue receipt kind)."),
|
|
546
|
+
id: z.string().describe('kind="media": mediaItemId returned by import/generate/finalize/import_resource. kind="render": renderId. kind="compose": composeJobId. kind="consult": consultJobId. kind="suggestions": mediaItemId. Generic kinds use the jobId from the enqueue receipt.'),
|
|
536
547
|
projectId: z.string().optional().describe('Required when kind="render", "compose", or "consult".'),
|
|
537
548
|
timeoutMs: z.number().int().min(1e3).max(30 * 60 * 1e3).optional().describe("Maximum wait in ms (default 30 min for render/compose, 5 min for suggestions).")
|
|
538
549
|
}
|
|
@@ -542,7 +553,7 @@ function registerWaitJob(server, ex, waitCapMs, onEvent) {
|
|
|
542
553
|
if ((kind === "render" || kind === "compose" || kind === "consult") && !args.projectId) {
|
|
543
554
|
return errText(`wait_job(kind="${kind}") requires a projectId.`);
|
|
544
555
|
}
|
|
545
|
-
const defaultCap = kind === "suggestions" ? 5 * 60 * 1e3 : 30 * 60 * 1e3;
|
|
556
|
+
const defaultCap = kind === "suggestions" || kind === "media" ? 5 * 60 * 1e3 : 30 * 60 * 1e3;
|
|
546
557
|
const requested = args.timeoutMs ?? defaultCap;
|
|
547
558
|
const deadline = Date.now() + (waitCapMs ? Math.min(requested, waitCapMs) : requested);
|
|
548
559
|
const res = await waitForJob(ex, kind, args.id, args.projectId, deadline);
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
COMPOSE_PLANNER_TOOLS,
|
|
3
3
|
COMPOSE_ROLE_TOOLS,
|
|
4
4
|
dispatchComposeRoleTool
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-D2EGO543.js";
|
|
6
6
|
|
|
7
7
|
// ../authoring/src/agent/buildTools.ts
|
|
8
8
|
import { tool } from "ai";
|
|
@@ -135,6 +135,22 @@ var buildPlannerTools = (p) => {
|
|
|
135
135
|
|
|
136
136
|
// ../authoring/src/agent/errors.ts
|
|
137
137
|
import { APICallError, TypeValidationError } from "ai";
|
|
138
|
+
var BODY_EXCERPT = 200;
|
|
139
|
+
function providerMessage(responseBody) {
|
|
140
|
+
if (!responseBody) return void 0;
|
|
141
|
+
try {
|
|
142
|
+
const body = JSON.parse(responseBody);
|
|
143
|
+
const msg = body?.error?.message ?? body?.message;
|
|
144
|
+
return msg == null ? void 0 : String(msg);
|
|
145
|
+
} catch {
|
|
146
|
+
return void 0;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function bodyExcerpt(responseBody) {
|
|
150
|
+
const trimmed = responseBody?.trim();
|
|
151
|
+
if (!trimmed) return void 0;
|
|
152
|
+
return trimmed.replace(/\s+/g, " ").slice(0, BODY_EXCERPT);
|
|
153
|
+
}
|
|
138
154
|
function extractProviderError(err) {
|
|
139
155
|
if (APICallError.isInstance(err)) {
|
|
140
156
|
const status = err.statusCode;
|
|
@@ -144,17 +160,16 @@ function extractProviderError(err) {
|
|
|
144
160
|
if (status === 429) {
|
|
145
161
|
return "API rate limit or quota exceeded. Try again later.";
|
|
146
162
|
}
|
|
163
|
+
const detail = providerMessage(err.responseBody);
|
|
147
164
|
if (status === 413 || status === 400) {
|
|
148
|
-
if (
|
|
149
|
-
try {
|
|
150
|
-
const body = JSON.parse(err.responseBody);
|
|
151
|
-
const msg = body?.error?.message ?? body?.message;
|
|
152
|
-
if (msg) return String(msg).slice(0, 200);
|
|
153
|
-
} catch {
|
|
154
|
-
}
|
|
155
|
-
}
|
|
165
|
+
if (detail) return detail.slice(0, 200);
|
|
156
166
|
}
|
|
157
|
-
|
|
167
|
+
const where = status === void 0 ? "" : ` (HTTP ${status})`;
|
|
168
|
+
const evidence = detail ?? bodyExcerpt(err.responseBody);
|
|
169
|
+
return (evidence ? `${err.message}${where}: ${evidence}` : `${err.message}${where}`).slice(
|
|
170
|
+
0,
|
|
171
|
+
300
|
|
172
|
+
);
|
|
158
173
|
}
|
|
159
174
|
if (TypeValidationError.isInstance(err)) {
|
|
160
175
|
return "Invalid response from AI provider. The provider may be misconfigured or unavailable.";
|