@hugpy/video-intelligence-ui 0.3.2 → 0.3.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/LICENSE +0 -0
- package/README.md +9 -0
- package/dist/assets/hugpy-mark-BXktFcOQ.png +0 -0
- package/dist/assets/index-DMoT8G1q.css +1 -0
- package/dist/assets/index-GeD1mo16.js +4190 -0
- package/dist/index.html +71 -0
- package/entry.tsx +6 -27
- package/index.html +4 -4
- package/package.json +44 -5
- package/src/assets/hugpy-mark.png +0 -0
- package/src/config.ts +11 -27
- package/src/demo/DemoBanner.tsx +0 -0
- package/src/demo/demo.css +0 -0
- package/src/demo/demoFetch.ts +0 -9
- package/src/demo/fixtures.ts +0 -0
- package/src/demo/identityFixture.ts +0 -0
- package/src/demo/index.ts +0 -0
- package/src/demo/mediaBase.ts +0 -0
- package/src/demo/mode.ts +0 -0
- package/src/demo/promptAssist.ts +0 -0
- package/src/demo/sampleData.ts +0 -0
- package/src/demo/sampleSets.ts +0 -0
- package/src/demo/seed.ts +0 -0
- package/src/nav/BrandMark.css +0 -0
- package/src/nav/BrandMark.tsx +0 -0
- package/src/nav/Navbar.css +0 -0
- package/src/nav/Navbar.tsx +8 -3
- package/src/regions/SpatialRegionEditor.tsx +0 -0
- package/src/regions/TemporalRegionEditor.tsx +0 -0
- package/src/regions/types.ts +0 -0
- package/src/session.ts +8 -43
- package/src/share.ts +0 -0
- package/src/stations/ActivePanel.tsx +0 -0
- package/src/stations/ActiveProcessesStation.tsx +0 -0
- package/src/stations/AddFileBar.tsx +0 -0
- package/src/stations/AudioCropStation.tsx +0 -0
- package/src/stations/ComfyPanel.tsx +0 -0
- package/src/stations/ComfyStation.tsx +0 -0
- package/src/stations/CondensedKnobStrip.tsx +0 -0
- package/src/stations/ConsolePanel.tsx +0 -0
- package/src/stations/FrameExtractStation.tsx +0 -0
- package/src/stations/GenIdentityBar.tsx +0 -0
- package/src/stations/GenerateStation.tsx +10 -6
- package/src/stations/GoalComposer.tsx +0 -0
- package/src/stations/ImageCropStation.tsx +0 -0
- package/src/stations/KnobInfo.tsx +0 -0
- package/src/stations/PlaceholderStation.tsx +0 -0
- package/src/stations/ScriptFirstStation.tsx +4 -0
- package/src/stations/SectionTabs.tsx +0 -0
- package/src/stations/SharePanel.tsx +4 -4
- package/src/stations/SidebarRegistry.tsx +0 -0
- package/src/stations/StationShell.tsx +0 -0
- package/src/stations/StudioClipsStation.tsx +0 -0
- package/src/stations/TemplateStepsPanel.tsx +190 -0
- package/src/stations/ToksPanel.tsx +1 -2
- package/src/stations/WorkbenchDrawer.tsx +0 -0
- package/src/stations/WorkbenchSidebar.tsx +8 -261
- package/src/stations/WorkbenchStation.tsx +0 -0
- package/src/stations/comfyEmbed.ts +0 -0
- package/src/stations/drawerShell.tsx +0 -0
- package/src/stations/ops/AudioCropCore.tsx +0 -0
- package/src/stations/ops/CharacterGroupsPanel.tsx +75 -83
- package/src/stations/ops/FrameExtractCore.tsx +0 -0
- package/src/stations/ops/ImageCropCore.tsx +0 -0
- package/src/stations/ops/VideoCropCore.tsx +0 -0
- package/src/stations/ops/useVideoCropJobs.ts +0 -0
- package/src/stations/oracle/DagPanel.tsx +0 -0
- package/src/stations/oracle/OracleStation.tsx +2 -0
- package/src/stations/oracle/PerformanceComposer.tsx +119 -0
- package/src/stations/oracle/SpatialTab.tsx +0 -0
- package/src/stations/oracle/StewardPanel.tsx +0 -0
- package/src/stations/oracle/oracle.css +33 -0
- package/src/stations/oracle/oracleShared.tsx +0 -0
- package/src/stations/oracle/oracleTypes.ts +0 -0
- package/src/stations/oracle/useOracle.ts +0 -0
- package/src/stations/pollCaps.ts +0 -0
- package/src/stations/registry.ts +0 -0
- package/src/stations/scriptFirst.css +23 -0
- package/src/stations/studio/AngleRingEditor.tsx +0 -0
- package/src/stations/studio/IdentitiesStation.tsx +86 -76
- package/src/stations/studio/IdentityCreatePanel.tsx +0 -0
- package/src/stations/studio/IdentityProfileControls.tsx +0 -0
- package/src/stations/studio/StudioActiveProcesses.tsx +0 -0
- package/src/stations/studio/StudioAssistLogPanel.tsx +0 -0
- package/src/stations/studio/StudioGenerateMode.tsx +3 -2
- package/src/stations/studio/StudioGenerateTab.tsx +278 -190
- package/src/stations/studio/StudioItemCard.tsx +0 -0
- package/src/stations/studio/StudioLibraryTab.tsx +0 -0
- package/src/stations/studio/StudioMovieComposer.tsx +321 -46
- package/src/stations/studio/StudioMovieSessions.tsx +12 -19
- package/src/stations/studio/StudioPlane.tsx +28 -5
- package/src/stations/studio/StudioSplicedRow.tsx +0 -0
- package/src/stations/studio/StudioViewer.tsx +6 -11
- package/src/stations/studio/TurntableViewer.tsx +0 -0
- package/src/stations/studio/coordinationBadge.tsx +0 -0
- package/src/stations/studio/identityUpload.ts +0 -0
- package/src/stations/studio/movieTimeline.ts +0 -0
- package/src/stations/studio/promptCard.tsx +0 -0
- package/src/stations/studio/studioItem.ts +0 -0
- package/src/stations/studio/studioShared.tsx +14 -2
- package/src/stations/studio/useIdentityCreateJob.ts +26 -21
- package/src/stations/studio/useIdentityProfiles.ts +0 -0
- package/src/stations/studio/useReconstruction.ts +11 -5
- package/src/stations/types.ts +0 -0
- package/src/stations/useAudioCropJobs.ts +0 -0
- package/src/stations/useAudioExtractJob.ts +0 -0
- package/src/stations/useCropJobs.ts +0 -0
- package/src/stations/useFrameJobs.ts +0 -0
- package/src/stations/useGenerateJob.ts +0 -0
- package/src/stations/useGenerateMovieJob.ts +0 -0
- package/src/stations/useGenerateRowJobs.ts +0 -0
- package/src/stations/useGenerateSceneJob.ts +0 -0
- package/src/stations/useGenerateSceneRowJobs.ts +0 -0
- package/src/stations/useScriptFirstRun.ts +0 -0
- package/src/style/app.css +49 -0
- package/src/transport/client.ts +0 -0
- package/src/transport/telemetry.ts +0 -0
- package/src/video/DropReceptacle.tsx +0 -0
- package/src/video/LengthRow.tsx +0 -0
- package/src/video/LibraryGroups.tsx +0 -0
- package/src/video/PromptAssistButtons.tsx +5 -4
- package/src/video/UnnamedWarn.tsx +0 -0
- package/src/video/composerBridge.ts +0 -0
- package/src/video/contract.ts +0 -0
- package/src/video/coordinationReport.ts +0 -0
- package/src/video/jobClock.ts +0 -0
- package/src/video/jobStream.ts +119 -0
- package/src/video/jobTracker.ts +67 -76
- package/src/video/mediaLibrary.ts +0 -0
- package/src/video/modelsFeed.ts +105 -0
- package/src/video/renderCompat.ts +0 -0
- package/src/video/sessionForm.ts +0 -0
- package/src/video/spreadAssist.ts +0 -0
- package/src/video/studioBridge.ts +0 -0
- package/src/video/studioOracle.ts +48 -0
- package/src/video/useMediaJobs.ts +17 -3
- package/src/video/useModels.ts +12 -53
- package/src/video/useMoviePresets.ts +0 -0
- package/src/video/useMovieSessions.ts +15 -6
- package/src/video/useOperatorHistory.ts +11 -101
- package/src/video/usePresets.ts +0 -0
- package/src/video/useProjects.ts +0 -0
- package/src/video/usePromptAssist.ts +70 -25
- package/src/video/useRenderPresets.ts +0 -0
- package/src/video/useStudioAssistLog.ts +0 -0
- package/src/video/useStudioPresets.ts +0 -0
- package/src/video/useToks.ts +14 -6
- package/src/video/watchVideoJob.ts +43 -0
- package/tsconfig.json +0 -0
- package/vite.config.ts +0 -0
- package/src/stations/studio/StudioMovieComposer.tsx.bak-declutter-20260813 +0 -3031
- package/src/video/useWorkerCalls.ts +0 -165
|
@@ -34,7 +34,8 @@ import * as THREE from "three";
|
|
|
34
34
|
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
|
|
35
35
|
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
36
36
|
import { request, okValue, errorOf, describeAppError } from "../../transport/client";
|
|
37
|
-
import { mediaBytesUrl, identityGenerateUrl, identityMeshStatusUrl
|
|
37
|
+
import { hugpyConfig, mediaBytesUrl, identityGenerateUrl, identityMeshStatusUrl } from "../../config";
|
|
38
|
+
import { watchVideoJob } from "../../video/watchVideoJob";
|
|
38
39
|
import { useMediaLibrary } from "../../video/mediaLibrary";
|
|
39
40
|
import type { LibraryItem } from "../../video/mediaLibrary";
|
|
40
41
|
import type { MediaRef, IdentityReconstruction, IdentityAngleView } from "../../video/contract";
|
|
@@ -529,12 +530,12 @@ export function ExtractFromVideoPanel({
|
|
|
529
530
|
const [pickError, setPickError] = useState<string | null>(null);
|
|
530
531
|
|
|
531
532
|
const active = useRef(false);
|
|
532
|
-
const
|
|
533
|
+
const jobStop = useRef<(() => void) | null>(null);
|
|
533
534
|
|
|
534
535
|
useEffect(() => {
|
|
535
536
|
return () => {
|
|
536
537
|
active.current = false;
|
|
537
|
-
|
|
538
|
+
jobStop.current?.();
|
|
538
539
|
};
|
|
539
540
|
}, []);
|
|
540
541
|
|
|
@@ -575,47 +576,34 @@ export function ExtractFromVideoPanel({
|
|
|
575
576
|
}
|
|
576
577
|
|
|
577
578
|
const jobId = enq.jobId;
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
if (!active.current) return;
|
|
581
|
-
|
|
579
|
+
jobStop.current?.();
|
|
580
|
+
jobStop.current = watchVideoJob(jobId, (row) => {
|
|
581
|
+
if (!active.current) return true;
|
|
582
|
+
const job = row as {
|
|
583
|
+
progress?: number | null;
|
|
584
|
+
result?: { ok?: boolean; error?: { code?: string; message?: string; retryable?: boolean } } | null;
|
|
585
|
+
stage?: string | null;
|
|
586
|
+
message?: string | null;
|
|
587
|
+
};
|
|
588
|
+
const result = job.result;
|
|
589
|
+
if (result && typeof result.ok === "boolean") {
|
|
582
590
|
active.current = false;
|
|
583
591
|
setBusy(false);
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
if (!active.current) return;
|
|
591
|
-
if (res.ok) {
|
|
592
|
-
const job = okValue(res) as {
|
|
593
|
-
progress?: number | null;
|
|
594
|
-
result?: { ok?: boolean; error?: { code?: string; message?: string; retryable?: boolean } } | null;
|
|
595
|
-
stage?: string | null;
|
|
596
|
-
message?: string | null;
|
|
597
|
-
};
|
|
598
|
-
const result = job.result;
|
|
599
|
-
if (result && typeof result.ok === "boolean") {
|
|
600
|
-
active.current = false;
|
|
601
|
-
setBusy(false);
|
|
602
|
-
if (result.ok) {
|
|
603
|
-
setStatus("done");
|
|
604
|
-
setVideo(null);
|
|
605
|
-
reload();
|
|
606
|
-
} else {
|
|
607
|
-
setStatus((result.error && result.error.message) || "Extraction failed.");
|
|
608
|
-
}
|
|
609
|
-
return;
|
|
610
|
-
}
|
|
611
|
-
const pct = typeof job.progress === "number" ? ` (${Math.round(job.progress * 100)}%)` : "";
|
|
612
|
-
const stage = job.stage || job.message;
|
|
613
|
-
setStatus(`Extracting…${pct}${stage ? ` — ${stage}` : ""}`);
|
|
592
|
+
if (result.ok) {
|
|
593
|
+
setStatus("done");
|
|
594
|
+
setVideo(null);
|
|
595
|
+
reload();
|
|
596
|
+
} else setStatus((result.error && result.error.message) || "Extraction failed.");
|
|
597
|
+
return true;
|
|
614
598
|
}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
599
|
+
const pct = typeof job.progress === "number" ? ` (${Math.round(job.progress * 100)}%)` : "";
|
|
600
|
+
const stage = job.stage || job.message;
|
|
601
|
+
setStatus(`Extracting…${pct}${stage ? ` — ${stage}` : ""}`);
|
|
602
|
+
}, () => {
|
|
603
|
+
active.current = false;
|
|
604
|
+
setBusy(false);
|
|
605
|
+
setStatus("Timed out waiting for the video extraction.");
|
|
606
|
+
}, 20 * 60 * 1000);
|
|
619
607
|
}
|
|
620
608
|
|
|
621
609
|
const canSubmit = video != null && !busy && uploadPhase === "idle";
|
|
@@ -1523,13 +1511,13 @@ function IdentityDetail({
|
|
|
1523
1511
|
// SUPERSEDED by the one-click mesh path for the identity gen flow — kept behind
|
|
1524
1512
|
// the "⚙ Settings & advanced" disclosure (see the render) so the tab stays to
|
|
1525
1513
|
// the point.
|
|
1526
|
-
const
|
|
1514
|
+
const genStop = useRef<(() => void) | null>(null);
|
|
1527
1515
|
const genActive = useRef(false);
|
|
1528
1516
|
// Stop the poll loop + free the timer when this card unmounts mid-build.
|
|
1529
1517
|
useEffect(() => {
|
|
1530
1518
|
return () => {
|
|
1531
1519
|
genActive.current = false;
|
|
1532
|
-
|
|
1520
|
+
genStop.current?.();
|
|
1533
1521
|
};
|
|
1534
1522
|
}, []);
|
|
1535
1523
|
|
|
@@ -1770,43 +1758,46 @@ function IdentityDetail({
|
|
|
1770
1758
|
return;
|
|
1771
1759
|
}
|
|
1772
1760
|
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
}
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
});
|
|
1786
|
-
if (!genActive.current) return;
|
|
1787
|
-
if (sres.ok) {
|
|
1788
|
-
const ms = okValue(sres) as { status?: string; error?: string | null };
|
|
1789
|
-
const st = ms.status ?? "queued";
|
|
1790
|
-
if (st === "done") {
|
|
1791
|
-
genActive.current = false;
|
|
1792
|
-
setGenBusy(false);
|
|
1793
|
-
setGenStatus("done");
|
|
1794
|
-
reload();
|
|
1795
|
-
return;
|
|
1796
|
-
}
|
|
1797
|
-
if (st === "error" || st === "cancelled") {
|
|
1761
|
+
if (!enq.job_id) {
|
|
1762
|
+
genActive.current = false;
|
|
1763
|
+
setGenBusy(false);
|
|
1764
|
+
setGenStatus("Generate response had no job_id.");
|
|
1765
|
+
return;
|
|
1766
|
+
}
|
|
1767
|
+
genStop.current?.();
|
|
1768
|
+
genStop.current = watchVideoJob(enq.job_id, (row) => {
|
|
1769
|
+
if (!genActive.current) return true;
|
|
1770
|
+
const result = row.result as { ok?: boolean; error?: { message?: string } } | null;
|
|
1771
|
+
if (result && typeof result.ok === "boolean") {
|
|
1772
|
+
if (!result.ok) {
|
|
1798
1773
|
genActive.current = false;
|
|
1799
1774
|
setGenBusy(false);
|
|
1800
|
-
setGenStatus(
|
|
1775
|
+
setGenStatus(result.error?.message || "3D identity build failed.");
|
|
1801
1776
|
reload();
|
|
1802
|
-
|
|
1777
|
+
} else {
|
|
1778
|
+
void request<unknown>(identityMeshStatusUrl(profile.slug, reconId), {
|
|
1779
|
+
meta: { specKey: "studio", operation: "identity.mesh.final" },
|
|
1780
|
+
}).then((sres) => {
|
|
1781
|
+
if (!genActive.current) return;
|
|
1782
|
+
genActive.current = false;
|
|
1783
|
+
setGenBusy(false);
|
|
1784
|
+
if (!sres.ok) setGenStatus(describeAppError(errorOf(sres)));
|
|
1785
|
+
else {
|
|
1786
|
+
const ms = okValue(sres) as { status?: string; error?: string | null };
|
|
1787
|
+
setGenStatus(ms.status === "done" ? "done" : ms.error || `Build ${ms.status || "unknown"}.`);
|
|
1788
|
+
}
|
|
1789
|
+
reload();
|
|
1790
|
+
});
|
|
1803
1791
|
}
|
|
1804
|
-
|
|
1792
|
+
return true;
|
|
1805
1793
|
}
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1794
|
+
setGenStatus(`Generating… (${String(row.current_stage || row.status || "running")})`);
|
|
1795
|
+
}, () => {
|
|
1796
|
+
genActive.current = false;
|
|
1797
|
+
setGenBusy(false);
|
|
1798
|
+
setGenStatus("Timed out waiting for the 3D identity build.");
|
|
1799
|
+
reload();
|
|
1800
|
+
}, 20 * 60 * 1000);
|
|
1810
1801
|
}
|
|
1811
1802
|
|
|
1812
1803
|
const { short: createdShort, full: createdFull } = fmtCreated(profile.created_at);
|
|
@@ -2149,6 +2140,17 @@ type IdTab = "active" | "session" | "settings";
|
|
|
2149
2140
|
|
|
2150
2141
|
export function IdentitiesStation({ spec }: { spec: StationSpec }) {
|
|
2151
2142
|
void spec;
|
|
2143
|
+
const [serviceProbe, setServiceProbe] = useState<{ configured: boolean; reachable: boolean; reason?: string; version?: string; capabilities?: Record<string, unknown> } | null>(null);
|
|
2144
|
+
useEffect(() => {
|
|
2145
|
+
let active = true;
|
|
2146
|
+
void (async () => {
|
|
2147
|
+
const result = await request<typeof serviceProbe>(`${hugpyConfig.apiBase}/video/identity-render/probe`, {
|
|
2148
|
+
meta: { specKey: "identities", operation: "identity.render.probe" },
|
|
2149
|
+
});
|
|
2150
|
+
if (active && result.ok) setServiceProbe(okValue(result));
|
|
2151
|
+
})();
|
|
2152
|
+
return () => { active = false; };
|
|
2153
|
+
}, []);
|
|
2152
2154
|
const {
|
|
2153
2155
|
profiles,
|
|
2154
2156
|
loading,
|
|
@@ -2225,6 +2227,14 @@ export function IdentitiesStation({ spec }: { spec: StationSpec }) {
|
|
|
2225
2227
|
return (
|
|
2226
2228
|
<section className="station-wide vi-identities vi-identities-md" aria-label="Identities workspace"
|
|
2227
2229
|
style={{ display: "grid", gridTemplateColumns: "300px minmax(0, 1fr)", gap: "1rem", alignItems: "start" }}>
|
|
2230
|
+
<div role="status" style={{ gridColumn: "1 / -1", padding: "0.55rem 0.75rem", border: "1px solid var(--vi-border)", borderRadius: "0.5rem", fontSize: "0.8rem" }}>
|
|
2231
|
+
<strong>Identity render service:</strong>{" "}
|
|
2232
|
+
{!serviceProbe ? "checking…" : serviceProbe.reachable
|
|
2233
|
+
? `online${serviceProbe.version ? ` · ${serviceProbe.version}` : ""}`
|
|
2234
|
+
: serviceProbe.reason || "unavailable"}
|
|
2235
|
+
{serviceProbe?.reachable && serviceProbe.capabilities ?
|
|
2236
|
+
<span> · {Object.entries(serviceProbe.capabilities).filter(([, value]) => Boolean(value)).map(([name]) => name).join(", ")}</span> : null}
|
|
2237
|
+
</div>
|
|
2228
2238
|
{/* ── SIDEBAR: tab filter + master list (wireframe b/c/d/f/e) ────────── */}
|
|
2229
2239
|
<aside className="vi-id-sidebar" aria-label="Identity list"
|
|
2230
2240
|
style={{ border: "1px solid var(--vi-border)", borderRadius: "0.5rem", padding: "0.5rem", position: "sticky", top: "0.5rem" }}>
|
|
@@ -2379,4 +2389,4 @@ export function IdentitiesStation({ spec }: { spec: StationSpec }) {
|
|
|
2379
2389
|
</div>
|
|
2380
2390
|
</section>
|
|
2381
2391
|
);
|
|
2382
|
-
}
|
|
2392
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -16,13 +16,14 @@ export interface StudioGenerateModeProps {
|
|
|
16
16
|
/** Set by the top-level Generate tab (Clip → "clip", Cinema → "movie") to lock the
|
|
17
17
|
* studio surface to one sub-mode and hide its internal Clip|Cinema switcher. */
|
|
18
18
|
lockedSurfaceMode?: "clip" | "movie";
|
|
19
|
+
onSelectSurfaceMode?: (mode: "clip" | "movie") => void;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
export function StudioGenerateMode({ lockedSurfaceMode }: StudioGenerateModeProps = {}) {
|
|
22
|
+
export function StudioGenerateMode({ lockedSurfaceMode, onSelectSurfaceMode }: StudioGenerateModeProps = {}) {
|
|
22
23
|
return (
|
|
23
24
|
<div className="vi-section-tabs vi-section-tabs--stacked">
|
|
24
25
|
<section className="vi-section-region vi-section-region--work" aria-label="Studio">
|
|
25
|
-
<StudioPlane lockedSurfaceMode={lockedSurfaceMode} />
|
|
26
|
+
<StudioPlane lockedSurfaceMode={lockedSurfaceMode} onSelectSurfaceMode={onSelectSurfaceMode} />
|
|
26
27
|
</section>
|
|
27
28
|
</div>
|
|
28
29
|
);
|