@hugpy/video-intelligence-ui 0.3.4 → 0.3.6
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/index.html
CHANGED
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
overflow-x: hidden;
|
|
50
50
|
}
|
|
51
51
|
</style>
|
|
52
|
-
<script type="module" crossorigin src="/video/assets/index
|
|
52
|
+
<script type="module" crossorigin src="/video/assets/index--is_kWXv.js"></script>
|
|
53
53
|
<link rel="stylesheet" crossorigin href="/video/assets/index-DMoT8G1q.css">
|
|
54
54
|
</head>
|
|
55
55
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hugpy/video-intelligence-ui",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Hugpy video-intelligence console: image crop, audio crop, frames/models and generate stations over the hugpy-video job bus; a standalone Vite + Tailwind v4 arm served at /video",
|
|
@@ -728,6 +728,18 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
|
|
|
728
728
|
// the warning is worth the one extra click. Session-persisted like every other authored
|
|
729
729
|
// field here.
|
|
730
730
|
const [movieTitle, setMovieTitle] = useSessionState("studio.movie.title", "");
|
|
731
|
+
const autoTitleRef = useSessionRef<string>("studio.movie.autoTitle", "");
|
|
732
|
+
const applyGeneratedTitle = useCallback((prompt: string, title?: string) => {
|
|
733
|
+
const derived = title?.trim() || prompt.split(/[.,;\n]/)[0].trim()
|
|
734
|
+
.split(/\s+/).slice(0, 7).join(" ").slice(0, 48);
|
|
735
|
+
if (!derived) return;
|
|
736
|
+
const previousAutoTitle = autoTitleRef.current;
|
|
737
|
+
setMovieTitle((current) => {
|
|
738
|
+
if (current.trim() && current.trim() !== previousAutoTitle) return current;
|
|
739
|
+
autoTitleRef.current = derived;
|
|
740
|
+
return derived;
|
|
741
|
+
});
|
|
742
|
+
}, [setMovieTitle, autoTitleRef]);
|
|
731
743
|
// Movie-level MODEL PIN + sampler overrides (operator ask 2026-07-13: the Settings tab
|
|
732
744
|
// wants "the model selection" + a wider range of options). All BLANK-first ⇒ router
|
|
733
745
|
// default: modelId "" = the capability router picks by budget/resolution (an unroutable
|
|
@@ -1306,13 +1318,6 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
|
|
|
1306
1318
|
);
|
|
1307
1319
|
const [producing, setProducing] = useState(false);
|
|
1308
1320
|
const [produceError, setProduceError] = useState<string | null>(null);
|
|
1309
|
-
// k120 slice 2 — render-time continuity: the runner rewrites each next segment
|
|
1310
|
-
// from the previous segment's ACTUAL closing frame. Auto-enabled by a
|
|
1311
|
-
// successful Produce (a scripted movie wants it); always operator-untickable.
|
|
1312
|
-
const [continuityRefresh, setContinuityRefresh] = useSessionState<boolean>(
|
|
1313
|
-
"studio.movie.continuityRefresh",
|
|
1314
|
-
false,
|
|
1315
|
-
);
|
|
1316
1321
|
const produceMovie = useCallback(async () => {
|
|
1317
1322
|
const p = premise.trim() || movieQuery.trim();
|
|
1318
1323
|
if (!p || producing) return;
|
|
@@ -1368,10 +1373,10 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
|
|
|
1368
1373
|
if (first.height != null && !manualSettings.current.includes("height")) setHeight(first.height);
|
|
1369
1374
|
if (first.fps != null && !manualSettings.current.includes("fps")) setFps(first.fps);
|
|
1370
1375
|
}
|
|
1376
|
+
applyGeneratedTitle(plan.segments[0]?.prompt || p, plan.title);
|
|
1371
1377
|
setProducerNote([plan.title, plan.logline].filter(Boolean).join(" — "));
|
|
1372
|
-
setContinuityRefresh(false);
|
|
1373
1378
|
}, [premise, movieQuery, producing, goals, fps, assist.assistModel, startImage,
|
|
1374
|
-
setWidth, setHeight, setFps,
|
|
1379
|
+
setWidth, setHeight, setFps, applyGeneratedTitle]);
|
|
1375
1380
|
|
|
1376
1381
|
const setSegmentCount = useCallback(
|
|
1377
1382
|
(n: number) => {
|
|
@@ -1485,7 +1490,6 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
|
|
|
1485
1490
|
// The last AUTO-derived movie title. A name the operator typed is sacred; a
|
|
1486
1491
|
// name this ref minted may be replaced by the next Generate (operator
|
|
1487
1492
|
// 2026-08-13: "purely a product of the same generation method").
|
|
1488
|
-
const autoTitleRef = useRef("");
|
|
1489
1493
|
const planGoalPrompt = useCallback(async (
|
|
1490
1494
|
i: number, text: string,
|
|
1491
1495
|
coordinated?: { seed?: number; frames?: number; joint_mode?: string },
|
|
@@ -1548,29 +1552,14 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
|
|
|
1548
1552
|
setGoalField(i, { negative: cur ? `${cur}, ${neg}` : neg });
|
|
1549
1553
|
},
|
|
1550
1554
|
);
|
|
1551
|
-
|
|
1552
|
-
// movie has none — or when the current one was itself auto-derived.
|
|
1553
|
-
const t = movieTitle.trim();
|
|
1554
|
-
if (t === "" || t === autoTitleRef.current) {
|
|
1555
|
-
const derived = fresh
|
|
1556
|
-
.split(/[.,;\n]/)[0]
|
|
1557
|
-
.trim()
|
|
1558
|
-
.split(/\s+/)
|
|
1559
|
-
.slice(0, 7)
|
|
1560
|
-
.join(" ")
|
|
1561
|
-
.slice(0, 48);
|
|
1562
|
-
if (derived) {
|
|
1563
|
-
autoTitleRef.current = derived;
|
|
1564
|
-
setMovieTitle(derived);
|
|
1565
|
-
}
|
|
1566
|
-
}
|
|
1555
|
+
applyGeneratedTitle(fresh);
|
|
1567
1556
|
})();
|
|
1568
1557
|
// The text is about to change, so the old classification no longer describes it.
|
|
1569
1558
|
intentText.current[g.key] = "";
|
|
1570
1559
|
setIntents((prev) => ({ ...prev, [g.key]: null }));
|
|
1571
1560
|
},
|
|
1572
1561
|
[assist, goals, rowContext, setGoalField, movieTitle, setMovieTitle,
|
|
1573
|
-
settingsMode, planGoalPrompt],
|
|
1562
|
+
settingsMode, planGoalPrompt, applyGeneratedTitle],
|
|
1574
1563
|
);
|
|
1575
1564
|
|
|
1576
1565
|
// ── negative generation (§1b) — an exclusion list for THIS shot ──
|
|
@@ -1606,7 +1595,7 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
|
|
|
1606
1595
|
});
|
|
1607
1596
|
if (!body) return;
|
|
1608
1597
|
setSpreadNotice(null);
|
|
1609
|
-
const res = await assist.runSpread(body);
|
|
1598
|
+
const res = await assist.runSpread({ ...body, fps });
|
|
1610
1599
|
if (!res) return;
|
|
1611
1600
|
|
|
1612
1601
|
const bySeg = new Map(res.segments.map((s) => [s.segment_id, s]));
|
|
@@ -1643,6 +1632,8 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
|
|
|
1643
1632
|
};
|
|
1644
1633
|
}),
|
|
1645
1634
|
);
|
|
1635
|
+
const firstGenerated = applied.length ? bySeg.get(applied[0]) : undefined;
|
|
1636
|
+
if (firstGenerated) applyGeneratedTitle(firstGenerated.prompt);
|
|
1646
1637
|
let oracleNotice: string | null = null;
|
|
1647
1638
|
if (settingsMode === "oracle") {
|
|
1648
1639
|
for (const key of applied) {
|
|
@@ -1693,6 +1684,8 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
|
|
|
1693
1684
|
steeringSeed,
|
|
1694
1685
|
settingsMode,
|
|
1695
1686
|
planGoalPrompt,
|
|
1687
|
+
applyGeneratedTitle,
|
|
1688
|
+
fps,
|
|
1696
1689
|
]);
|
|
1697
1690
|
|
|
1698
1691
|
// ── GROUP ACTION: negatives for the selected rows ──
|
|
@@ -1909,13 +1902,9 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
|
|
|
1909
1902
|
reference_images:
|
|
1910
1903
|
!selectedProfile && references.length ? references.map((r) => r.uri) : undefined,
|
|
1911
1904
|
goals: goalBodies,
|
|
1912
|
-
// k120 slice 2 — PRODUCER CONTINUITY REFRESH: the runner rewrites each
|
|
1913
|
-
// non-root segment's prompt from a vision read of the frame the previous
|
|
1914
|
-
// segment actually ended on. Off drops the key (schema default False).
|
|
1915
|
-
continuity_refresh: continuityRefresh || undefined,
|
|
1916
1905
|
};
|
|
1917
1906
|
return { body };
|
|
1918
|
-
}, [goals, width, height, fps, seed, vramBudget, modelId, steps, cfg, negative, project, movieTitle, startImage, references, selectedProfile,
|
|
1907
|
+
}, [goals, width, height, fps, seed, vramBudget, modelId, steps, cfg, negative, project, movieTitle, startImage, references, selectedProfile, settingsMode]);
|
|
1919
1908
|
|
|
1920
1909
|
// NAME NUDGE (k91) — set when a submit was held back only because the movie has no
|
|
1921
1910
|
// name. It is a warning, not a gate: the run row then offers "Generate without a
|
|
@@ -71,6 +71,7 @@ export interface AssistContextWire {
|
|
|
71
71
|
/** The `mode:"spread"` request body (§1a), minus `model` (the hook adds that). */
|
|
72
72
|
export interface SpreadRequestWire {
|
|
73
73
|
mode: "spread";
|
|
74
|
+
fps?: number;
|
|
74
75
|
movie_query?: string;
|
|
75
76
|
style_bible?: Record<string, string>;
|
|
76
77
|
fixed_segments: SegmentRefWire[];
|