@adminide-stack/yantra-mobile 12.0.121 → 12.0.123-alpha.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/lib/features/apps/appArt.js +1 -1
- package/lib/features/apps/appArt.js.map +1 -1
- package/lib/features/apps/mobileAppCatalog.js +15 -11
- package/lib/features/apps/mobileAppCatalog.js.map +1 -1
- package/lib/features/canvas/CanvasAgentChatPane.js +82 -20
- package/lib/features/canvas/CanvasAgentChatPane.js.map +1 -1
- package/lib/features/canvas/CanvasBoardsGrid.js +291 -100
- package/lib/features/canvas/CanvasBoardsGrid.js.map +1 -1
- package/lib/features/canvas/CanvasEditToolsPanel.js +105 -12
- package/lib/features/canvas/CanvasEditToolsPanel.js.map +1 -1
- package/lib/features/canvas/CanvasExperience.js +266 -68
- package/lib/features/canvas/CanvasExperience.js.map +1 -1
- package/lib/features/canvas/CanvasGeneratePanel.js +204 -66
- package/lib/features/canvas/CanvasGeneratePanel.js.map +1 -1
- package/lib/features/canvas/CanvasLibrarySheet.js +31 -13
- package/lib/features/canvas/CanvasLibrarySheet.js.map +1 -1
- package/lib/features/canvas/CanvasModelPicker.js +176 -0
- package/lib/features/canvas/CanvasModelPicker.js.map +1 -0
- package/lib/features/canvas/CanvasTasksPanel.js +325 -29
- package/lib/features/canvas/CanvasTasksPanel.js.map +1 -1
- package/lib/features/canvas/CanvasTemplatesPanel.js +5 -4
- package/lib/features/canvas/CanvasTemplatesPanel.js.map +1 -1
- package/lib/features/canvas/CanvasToolDock.js +137 -61
- package/lib/features/canvas/CanvasToolDock.js.map +1 -1
- package/lib/features/canvas/FrameExtractorExperience.js +33 -2
- package/lib/features/canvas/FrameExtractorExperience.js.map +1 -1
- package/lib/features/canvas/GeneratorReferenceSlots.js +197 -0
- package/lib/features/canvas/GeneratorReferenceSlots.js.map +1 -0
- package/lib/features/canvas/NativeCanvasViewer.js +89 -11
- package/lib/features/canvas/NativeCanvasViewer.js.map +1 -1
- package/lib/features/canvas/PromoContextFields.js +55 -2
- package/lib/features/canvas/PromoContextFields.js.map +1 -1
- package/lib/features/canvas/SetStudioExperience.js +323 -13
- package/lib/features/canvas/SetStudioExperience.js.map +1 -1
- package/lib/features/canvas/VideoEditExperience.js +1 -53
- package/lib/features/canvas/VideoEditExperience.js.map +1 -1
- package/lib/features/canvas/VideoEditorExperience.js +697 -506
- package/lib/features/canvas/VideoEditorExperience.js.map +1 -1
- package/lib/features/canvas/VideoGeneratorExperience.js +22 -5
- package/lib/features/canvas/VideoGeneratorExperience.js.map +1 -1
- package/lib/features/canvas/canvasAgentChat.js +125 -11
- package/lib/features/canvas/canvasAgentChat.js.map +1 -1
- package/lib/features/canvas/canvasCore.js +117 -12
- package/lib/features/canvas/canvasCore.js.map +1 -1
- package/lib/features/canvas/canvasEditOps.js +148 -111
- package/lib/features/canvas/canvasEditOps.js.map +1 -1
- package/lib/features/canvas/canvasTaskSync.js +235 -0
- package/lib/features/canvas/canvasTaskSync.js.map +1 -0
- package/lib/features/canvas/canvasTasks.js +98 -11
- package/lib/features/canvas/canvasTasks.js.map +1 -1
- package/lib/features/canvas/createTiles.js +247 -0
- package/lib/features/canvas/createTiles.js.map +1 -0
- package/lib/features/canvas/deepLinks.js +83 -0
- package/lib/features/canvas/deepLinks.js.map +1 -0
- package/lib/features/canvas/frameExtract.js +13 -1
- package/lib/features/canvas/frameExtract.js.map +1 -1
- package/lib/features/canvas/generationModels.js +36 -8
- package/lib/features/canvas/generationModels.js.map +1 -1
- package/lib/features/canvas/generatorCommands.js +106 -0
- package/lib/features/canvas/generatorCommands.js.map +1 -0
- package/lib/features/canvas/generatorReferences.js +82 -0
- package/lib/features/canvas/generatorReferences.js.map +1 -0
- package/lib/features/canvas/homeWork.js +74 -0
- package/lib/features/canvas/homeWork.js.map +1 -0
- package/lib/features/canvas/linksRpc.js +130 -0
- package/lib/features/canvas/linksRpc.js.map +1 -0
- package/lib/features/canvas/mediaRecheck.js +176 -0
- package/lib/features/canvas/mediaRecheck.js.map +1 -0
- package/lib/features/canvas/mediaUrls.js +258 -0
- package/lib/features/canvas/mediaUrls.js.map +1 -0
- package/lib/features/canvas/nativeViewerRegistry.js.map +1 -1
- package/lib/features/canvas/promoProjectImport.js +80 -13
- package/lib/features/canvas/promoProjectImport.js.map +1 -1
- package/lib/features/canvas/promoVideo.js +106 -15
- package/lib/features/canvas/promoVideo.js.map +1 -1
- package/lib/features/canvas/reframe.js +228 -0
- package/lib/features/canvas/reframe.js.map +1 -0
- package/lib/features/canvas/serverTasks.js +697 -0
- package/lib/features/canvas/serverTasks.js.map +1 -0
- package/lib/features/canvas/set/SetViewportWebView.js +207 -28
- package/lib/features/canvas/set/SetViewportWebView.js.map +1 -1
- package/lib/features/canvas/set/agent/prompt.js +66 -0
- package/lib/features/canvas/set/agent/prompt.js.map +1 -0
- package/lib/features/canvas/set/agent/setOps.js +203 -0
- package/lib/features/canvas/set/agent/setOps.js.map +1 -0
- package/lib/features/canvas/set/agent/setTurn.js +128 -0
- package/lib/features/canvas/set/agent/setTurn.js.map +1 -0
- package/lib/features/canvas/set/agent/snapshot.js +43 -0
- package/lib/features/canvas/set/agent/snapshot.js.map +1 -0
- package/lib/features/canvas/set/agent/tools.js +580 -0
- package/lib/features/canvas/set/agent/tools.js.map +1 -0
- package/lib/features/canvas/set/setProject.js +43 -4
- package/lib/features/canvas/set/setProject.js.map +1 -1
- package/lib/features/canvas/set/supplyLibrary.js +397 -0
- package/lib/features/canvas/set/supplyLibrary.js.map +1 -0
- package/lib/features/canvas/storageLibrary.js +113 -52
- package/lib/features/canvas/storageLibrary.js.map +1 -1
- package/lib/features/canvas/studioCatalog.js +15 -2
- package/lib/features/canvas/studioCatalog.js.map +1 -1
- package/lib/features/canvas/studioLooks.js +1 -8
- package/lib/features/canvas/studioLooks.js.map +1 -1
- package/lib/features/canvas/useBoardMediaRefresh.js +66 -0
- package/lib/features/canvas/useBoardMediaRefresh.js.map +1 -0
- package/lib/features/canvas/useMediaSource.js +84 -0
- package/lib/features/canvas/useMediaSource.js.map +1 -0
- package/lib/features/canvas/video3d.js +11 -10
- package/lib/features/canvas/video3d.js.map +1 -1
- package/lib/features/canvas/videoEditor/BlurBoxOverlay.js +46 -0
- package/lib/features/canvas/videoEditor/BlurBoxOverlay.js.map +1 -0
- package/lib/features/canvas/videoEditor/ExportTaskCard.js +134 -0
- package/lib/features/canvas/videoEditor/ExportTaskCard.js.map +1 -0
- package/lib/features/canvas/videoEditor/agent/AgentCutPane.js +45 -7
- package/lib/features/canvas/videoEditor/agent/AgentCutPane.js.map +1 -1
- package/lib/features/canvas/videoEditor/agent/agentLoop.js +4 -2
- package/lib/features/canvas/videoEditor/agent/agentLoop.js.map +1 -1
- package/lib/features/canvas/videoEditor/agent/attachments.js +304 -0
- package/lib/features/canvas/videoEditor/agent/attachments.js.map +1 -0
- package/lib/features/canvas/videoEditor/agent/brainClient.js +3 -2
- package/lib/features/canvas/videoEditor/agent/brainClient.js.map +1 -1
- package/lib/features/canvas/videoEditor/agent/cutTools.js +207 -7
- package/lib/features/canvas/videoEditor/agent/cutTools.js.map +1 -1
- package/lib/features/canvas/videoEditor/blurBox.js +34 -0
- package/lib/features/canvas/videoEditor/blurBox.js.map +1 -0
- package/lib/features/canvas/videoEditor/compileTimeline.js +668 -0
- package/lib/features/canvas/videoEditor/compileTimeline.js.map +1 -0
- package/lib/features/canvas/videoEditor/editorModel.js +56 -22
- package/lib/features/canvas/videoEditor/editorModel.js.map +1 -1
- package/lib/features/canvas/videoEditor/exportPipeline.js +77 -0
- package/lib/features/canvas/videoEditor/exportPipeline.js.map +1 -0
- package/lib/features/canvas/videoEditor/exportRenderer.js +19 -12
- package/lib/features/canvas/videoEditor/exportRenderer.js.map +1 -1
- package/lib/features/canvas/videoEditor/exportTask.js +216 -0
- package/lib/features/canvas/videoEditor/exportTask.js.map +1 -0
- package/lib/features/canvas/videoEditor/formWidgets.js +142 -0
- package/lib/features/canvas/videoEditor/formWidgets.js.map +1 -0
- package/lib/features/canvas/videoEditor/produce/ProduceVideoSheet.js +195 -0
- package/lib/features/canvas/videoEditor/produce/ProduceVideoSheet.js.map +1 -0
- package/lib/features/canvas/videoEditor/produce/produceScenes.js +158 -0
- package/lib/features/canvas/videoEditor/produce/produceScenes.js.map +1 -0
- package/lib/features/canvas/videoEditor/remoteMediaClient.js +17 -5
- package/lib/features/canvas/videoEditor/remoteMediaClient.js.map +1 -1
- package/lib/features/canvas/videoEditor/renderTimeline.js +207 -0
- package/lib/features/canvas/videoEditor/renderTimeline.js.map +1 -0
- package/lib/features/canvas/videoEditor/renewLinks.js +64 -0
- package/lib/features/canvas/videoEditor/renewLinks.js.map +1 -0
- package/lib/features/canvas/videoEditor/sceneLayers.js +101 -0
- package/lib/features/canvas/videoEditor/sceneLayers.js.map +1 -0
- package/lib/features/canvas/videoEditor/tools/ToolsDrawer.js +283 -0
- package/lib/features/canvas/videoEditor/tools/ToolsDrawer.js.map +1 -0
- package/lib/features/canvas/videoEditor/tools/catalog.js +576 -0
- package/lib/features/canvas/videoEditor/tools/catalog.js.map +1 -0
- package/lib/features/canvas/videoEditor/videoProjectsStore.js +27 -3
- package/lib/features/canvas/videoEditor/videoProjectsStore.js.map +1 -1
- package/lib/features/webbuilder/WebBuilderExperience.js +29 -1
- package/lib/features/webbuilder/WebBuilderExperience.js.map +1 -1
- package/lib/features/webbuilder/buildFragments.js +8 -4
- package/lib/features/webbuilder/buildFragments.js.map +1 -1
- package/lib/features/webbuilder/codezenHandoff.js +108 -0
- package/lib/features/webbuilder/codezenHandoff.js.map +1 -0
- package/lib/features/webbuilder/workflow.js.map +1 -1
- package/lib/hooks/useChatApi.js +1 -2
- package/lib/hooks/useChatApi.js.map +1 -1
- package/lib/screens/CanvasBoard/index.js +12 -1
- package/lib/screens/CanvasBoard/index.js.map +1 -1
- package/lib/screens/Home/HomeScreen.js.map +1 -1
- package/lib/screens/Home/components/HomeSuggestions.js +3 -3
- package/lib/screens/Home/components/HomeSuggestions.js.map +1 -1
- package/lib/screens/WebBuilder/index.js +4 -2
- package/lib/screens/WebBuilder/index.js.map +1 -1
- package/lib/screens/WebBuilderNative/index.js +29 -2
- package/lib/screens/WebBuilderNative/index.js.map +1 -1
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js +30 -6
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -1
- package/package.json +4 -4
- /package/lib/assets/apps/{paper2poster.webp → poster.webp} +0 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import {jsxs,jsx}from'react/jsx-runtime';import {useMemo,useState}from'react';import {StyleSheet,Modal,Pressable,View,Text,ScrollView,ActivityIndicator,TextInput}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {STATIC_VIDEO_MODELS}from'../../generationModels.js';import {produceScenes,produceSummary,produceJob,runProduce}from'./produceScenes.js';var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
var _a;
|
|
21
|
+
const MODEL = STATIC_VIDEO_MODELS[0];
|
|
22
|
+
const DURATIONS = (_a = MODEL == null ? void 0 : MODEL.supportedDurationsSeconds) != null ? _a : [4, 6, 8];
|
|
23
|
+
function ProduceVideoSheet({
|
|
24
|
+
visible,
|
|
25
|
+
onClose,
|
|
26
|
+
timeline,
|
|
27
|
+
sourceSec,
|
|
28
|
+
aspectRatio,
|
|
29
|
+
runAction,
|
|
30
|
+
onFootage
|
|
31
|
+
}) {
|
|
32
|
+
var _a2;
|
|
33
|
+
const scenes = useMemo(() => produceScenes(timeline, sourceSec), [timeline, sourceSec]);
|
|
34
|
+
const [picked, setPicked] = useState({});
|
|
35
|
+
const [shots, setShots] = useState({});
|
|
36
|
+
const [status, setStatus] = useState({});
|
|
37
|
+
const [running, setRunning] = useState(false);
|
|
38
|
+
const isPicked = (id, hasFootage) => {
|
|
39
|
+
var _a3;
|
|
40
|
+
return (_a3 = picked[id]) != null ? _a3 : !hasFootage;
|
|
41
|
+
};
|
|
42
|
+
const chosen = scenes.filter((s) => isPicked(s.sceneId, s.hasFootage));
|
|
43
|
+
const start = () => {
|
|
44
|
+
if (!runAction || running || chosen.length === 0) return;
|
|
45
|
+
setRunning(true);
|
|
46
|
+
const jobs = chosen.map((s) => {
|
|
47
|
+
var _a3;
|
|
48
|
+
return produceJob(s, DURATIONS, ((_a3 = shots[s.sceneId]) == null ? void 0 : _a3.trim()) || s.shot);
|
|
49
|
+
});
|
|
50
|
+
void runProduce(jobs, runAction, {
|
|
51
|
+
aspectRatio,
|
|
52
|
+
model: MODEL == null ? void 0 : MODEL.id,
|
|
53
|
+
onStatus: (sceneId, next) => {
|
|
54
|
+
setStatus((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
55
|
+
[sceneId]: next
|
|
56
|
+
}));
|
|
57
|
+
if (next.state === "done") onFootage(sceneId, next.footage);
|
|
58
|
+
}
|
|
59
|
+
}).finally(() => setRunning(false));
|
|
60
|
+
};
|
|
61
|
+
return /* @__PURE__ */ jsxs(Modal, { visible, transparent: true, animationType: "slide", onRequestClose: onClose, children: [
|
|
62
|
+
/* @__PURE__ */ jsx(Pressable, { style: styles.scrim, onPress: running ? void 0 : onClose, accessibilityLabel: "Close" }),
|
|
63
|
+
/* @__PURE__ */ jsxs(View, { style: styles.sheet, testID: "produce-video-sheet", children: [
|
|
64
|
+
/* @__PURE__ */ jsxs(View, { style: styles.header, children: [
|
|
65
|
+
/* @__PURE__ */ jsx(Text, { style: styles.title, children: "Produce video" }),
|
|
66
|
+
/* @__PURE__ */ jsx(Pressable, { onPress: onClose, hitSlop: 10, accessibilityRole: "button", accessibilityLabel: "Close", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "close", size: 22, color: "#F7F7FA" }) })
|
|
67
|
+
] }),
|
|
68
|
+
/* @__PURE__ */ jsxs(Text, { style: styles.hint, children: [
|
|
69
|
+
"Films each chosen scene with ",
|
|
70
|
+
(_a2 = MODEL == null ? void 0 : MODEL.label) != null ? _a2 : "the video model",
|
|
71
|
+
" and puts the clip under its titles. The scene keeps its length, layers and transition."
|
|
72
|
+
] }),
|
|
73
|
+
/* @__PURE__ */ jsxs(ScrollView, { contentContainerStyle: styles.list, keyboardShouldPersistTaps: "handled", children: [
|
|
74
|
+
scenes.length === 0 ? /* @__PURE__ */ jsx(Text, { style: styles.hint, children: "Add scenes first." }) : null,
|
|
75
|
+
scenes.map((s) => {
|
|
76
|
+
var _a3;
|
|
77
|
+
const on = isPicked(s.sceneId, s.hasFootage);
|
|
78
|
+
const st = status[s.sceneId];
|
|
79
|
+
return /* @__PURE__ */ jsxs(View, { style: [styles.row, on && styles.rowOn], children: [
|
|
80
|
+
/* @__PURE__ */ jsxs(Pressable, { onPress: () => setPicked((p) => __spreadProps(__spreadValues({}, p), {
|
|
81
|
+
[s.sceneId]: !on
|
|
82
|
+
})), disabled: running, style: styles.rowHead, accessibilityRole: "checkbox", accessibilityState: {
|
|
83
|
+
checked: on
|
|
84
|
+
}, children: [
|
|
85
|
+
/* @__PURE__ */ jsx(MaterialCommunityIcons, { name: on ? "checkbox-marked" : "checkbox-blank-outline", size: 18, color: on ? "#8B7CFF" : "#6A6A75" }),
|
|
86
|
+
/* @__PURE__ */ jsx(Text, { style: styles.label, numberOfLines: 1, children: s.label }),
|
|
87
|
+
/* @__PURE__ */ jsxs(Text, { style: styles.meta, children: [
|
|
88
|
+
s.seconds,
|
|
89
|
+
"s",
|
|
90
|
+
s.hasFootage ? " \xB7 has footage" : ""
|
|
91
|
+
] }),
|
|
92
|
+
(st == null ? void 0 : st.state) === "filming" ? /* @__PURE__ */ jsx(ActivityIndicator, { size: "small", color: "#8B7CFF" }) : null,
|
|
93
|
+
(st == null ? void 0 : st.state) === "done" ? /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "check-circle", size: 16, color: "#34D399" }) : null
|
|
94
|
+
] }),
|
|
95
|
+
on ? /* @__PURE__ */ jsx(TextInput, { value: (_a3 = shots[s.sceneId]) != null ? _a3 : s.shot, onChangeText: (text) => setShots((p) => __spreadProps(__spreadValues({}, p), {
|
|
96
|
+
[s.sceneId]: text
|
|
97
|
+
})), editable: !running, multiline: true, style: styles.shot, placeholderTextColor: "#5A5A66" }) : null,
|
|
98
|
+
(st == null ? void 0 : st.state) === "failed" ? /* @__PURE__ */ jsx(Text, { style: styles.error, children: st.message }) : null
|
|
99
|
+
] }, s.sceneId);
|
|
100
|
+
})
|
|
101
|
+
] }),
|
|
102
|
+
/* @__PURE__ */ jsx(Pressable, { onPress: start, disabled: !runAction || running || chosen.length === 0, style: [styles.run, (!runAction || running || chosen.length === 0) && styles.runOff], accessibilityRole: "button", children: running ? /* @__PURE__ */ jsx(ActivityIndicator, { color: "#0A0A0C" }) : /* @__PURE__ */ jsxs(Text, { style: styles.runLabel, children: [
|
|
103
|
+
"Film ",
|
|
104
|
+
produceSummary(chosen, DURATIONS)
|
|
105
|
+
] }) })
|
|
106
|
+
] })
|
|
107
|
+
] });
|
|
108
|
+
}
|
|
109
|
+
const styles = StyleSheet.create({
|
|
110
|
+
scrim: {
|
|
111
|
+
flex: 1,
|
|
112
|
+
backgroundColor: "rgba(0,0,0,0.45)"
|
|
113
|
+
},
|
|
114
|
+
sheet: {
|
|
115
|
+
maxHeight: "82%",
|
|
116
|
+
backgroundColor: "#141418",
|
|
117
|
+
borderTopLeftRadius: 18,
|
|
118
|
+
borderTopRightRadius: 18,
|
|
119
|
+
paddingHorizontal: 16,
|
|
120
|
+
paddingBottom: 28,
|
|
121
|
+
gap: 10
|
|
122
|
+
},
|
|
123
|
+
header: {
|
|
124
|
+
flexDirection: "row",
|
|
125
|
+
alignItems: "center",
|
|
126
|
+
paddingTop: 14
|
|
127
|
+
},
|
|
128
|
+
title: {
|
|
129
|
+
flex: 1,
|
|
130
|
+
color: "#F7F7FA",
|
|
131
|
+
fontSize: 16,
|
|
132
|
+
fontWeight: "700"
|
|
133
|
+
},
|
|
134
|
+
hint: {
|
|
135
|
+
color: "#8B8B96",
|
|
136
|
+
fontSize: 12.5,
|
|
137
|
+
lineHeight: 17
|
|
138
|
+
},
|
|
139
|
+
list: {
|
|
140
|
+
gap: 8,
|
|
141
|
+
paddingVertical: 6
|
|
142
|
+
},
|
|
143
|
+
row: {
|
|
144
|
+
gap: 6,
|
|
145
|
+
padding: 10,
|
|
146
|
+
borderRadius: 12,
|
|
147
|
+
backgroundColor: "#1B1B21"
|
|
148
|
+
},
|
|
149
|
+
rowOn: {
|
|
150
|
+
borderWidth: 1,
|
|
151
|
+
borderColor: "#3B3366"
|
|
152
|
+
},
|
|
153
|
+
rowHead: {
|
|
154
|
+
flexDirection: "row",
|
|
155
|
+
alignItems: "center",
|
|
156
|
+
gap: 8
|
|
157
|
+
},
|
|
158
|
+
label: {
|
|
159
|
+
flex: 1,
|
|
160
|
+
color: "#F7F7FA",
|
|
161
|
+
fontSize: 13.5,
|
|
162
|
+
fontWeight: "600"
|
|
163
|
+
},
|
|
164
|
+
meta: {
|
|
165
|
+
color: "#8B8B96",
|
|
166
|
+
fontSize: 12
|
|
167
|
+
},
|
|
168
|
+
shot: {
|
|
169
|
+
color: "#E4E4EA",
|
|
170
|
+
fontSize: 12.5,
|
|
171
|
+
minHeight: 48,
|
|
172
|
+
padding: 8,
|
|
173
|
+
borderRadius: 8,
|
|
174
|
+
backgroundColor: "#24242B",
|
|
175
|
+
textAlignVertical: "top"
|
|
176
|
+
},
|
|
177
|
+
error: {
|
|
178
|
+
color: "#F87171",
|
|
179
|
+
fontSize: 12
|
|
180
|
+
},
|
|
181
|
+
run: {
|
|
182
|
+
alignItems: "center",
|
|
183
|
+
paddingVertical: 13,
|
|
184
|
+
borderRadius: 12,
|
|
185
|
+
backgroundColor: "#8B7CFF"
|
|
186
|
+
},
|
|
187
|
+
runOff: {
|
|
188
|
+
opacity: 0.4
|
|
189
|
+
},
|
|
190
|
+
runLabel: {
|
|
191
|
+
color: "#0A0A0C",
|
|
192
|
+
fontSize: 14,
|
|
193
|
+
fontWeight: "700"
|
|
194
|
+
}
|
|
195
|
+
});export{ProduceVideoSheet};//# sourceMappingURL=ProduceVideoSheet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProduceVideoSheet.js","sources":["../../../../../src/features/canvas/videoEditor/produce/ProduceVideoSheet.tsx"],"sourcesContent":["/**\n * Produce video sheet (web produce/ProduceVideoSheet.tsx): lists the cut's\n * scenes with their shots, films the chosen ones with an AI video model -\n * two at a time - and swaps each colour scene for its clip as it lands.\n */\nimport React, { useMemo, useState } from 'react';\nimport { ActivityIndicator, Modal, Pressable, ScrollView, StyleSheet, Text, TextInput, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { STATIC_VIDEO_MODELS } from '../../generationModels';\nimport type { EditorTimeline } from '../editorModel';\nimport type { RunMediaAction } from '../mediaActions';\nimport {\n produceJob,\n produceScenes,\n produceSummary,\n runProduce,\n type ProduceStatus,\n type SceneFootage,\n} from './produceScenes';\n\nexport interface ProduceVideoSheetProps {\n visible: boolean;\n onClose: () => void;\n timeline: EditorTimeline;\n sourceSec: Readonly<Record<string, number>>;\n aspectRatio: string;\n runAction?: RunMediaAction;\n /** A scene's footage came back: swap it in. */\n onFootage: (sceneId: string, footage: SceneFootage) => void;\n}\n\nconst MODEL = STATIC_VIDEO_MODELS[0];\nconst DURATIONS = MODEL?.supportedDurationsSeconds ?? [4, 6, 8];\n\nexport function ProduceVideoSheet({\n visible,\n onClose,\n timeline,\n sourceSec,\n aspectRatio,\n runAction,\n onFootage,\n}: ProduceVideoSheetProps) {\n const scenes = useMemo(() => produceScenes(timeline, sourceSec), [timeline, sourceSec]);\n const [picked, setPicked] = useState<Record<string, boolean>>({});\n const [shots, setShots] = useState<Record<string, string>>({});\n const [status, setStatus] = useState<Record<string, ProduceStatus>>({});\n const [running, setRunning] = useState(false);\n\n const isPicked = (id: string, hasFootage: boolean) => picked[id] ?? !hasFootage;\n const chosen = scenes.filter((s) => isPicked(s.sceneId, s.hasFootage));\n\n const start = () => {\n if (!runAction || running || chosen.length === 0) return;\n setRunning(true);\n const jobs = chosen.map((s) => produceJob(s, DURATIONS, shots[s.sceneId]?.trim() || s.shot));\n void runProduce(jobs, runAction, {\n aspectRatio,\n model: MODEL?.id,\n onStatus: (sceneId, next) => {\n setStatus((prev) => ({ ...prev, [sceneId]: next }));\n if (next.state === 'done') onFootage(sceneId, next.footage);\n },\n }).finally(() => setRunning(false));\n };\n\n return (\n <Modal visible={visible} transparent animationType=\"slide\" onRequestClose={onClose}>\n <Pressable style={styles.scrim} onPress={running ? undefined : onClose} accessibilityLabel=\"Close\" />\n <View style={styles.sheet} testID=\"produce-video-sheet\">\n <View style={styles.header}>\n <Text style={styles.title}>Produce video</Text>\n <Pressable onPress={onClose} hitSlop={10} accessibilityRole=\"button\" accessibilityLabel=\"Close\">\n <MaterialCommunityIcons name=\"close\" size={22} color=\"#F7F7FA\" />\n </Pressable>\n </View>\n <Text style={styles.hint}>\n Films each chosen scene with {MODEL?.label ?? 'the video model'} and puts the clip under its titles.\n The scene keeps its length, layers and transition.\n </Text>\n <ScrollView contentContainerStyle={styles.list} keyboardShouldPersistTaps=\"handled\">\n {scenes.length === 0 ? <Text style={styles.hint}>Add scenes first.</Text> : null}\n {scenes.map((s) => {\n const on = isPicked(s.sceneId, s.hasFootage);\n const st = status[s.sceneId];\n return (\n <View key={s.sceneId} style={[styles.row, on && styles.rowOn]}>\n <Pressable\n onPress={() => setPicked((p) => ({ ...p, [s.sceneId]: !on }))}\n disabled={running}\n style={styles.rowHead}\n accessibilityRole=\"checkbox\"\n accessibilityState={{ checked: on }}\n >\n <MaterialCommunityIcons\n name={on ? 'checkbox-marked' : 'checkbox-blank-outline'}\n size={18}\n color={on ? '#8B7CFF' : '#6A6A75'}\n />\n <Text style={styles.label} numberOfLines={1}>\n {s.label}\n </Text>\n <Text style={styles.meta}>\n {s.seconds}s{s.hasFootage ? ' · has footage' : ''}\n </Text>\n {st?.state === 'filming' ? (\n <ActivityIndicator size=\"small\" color=\"#8B7CFF\" />\n ) : null}\n {st?.state === 'done' ? (\n <MaterialCommunityIcons name=\"check-circle\" size={16} color=\"#34D399\" />\n ) : null}\n </Pressable>\n {on ? (\n <TextInput\n value={shots[s.sceneId] ?? s.shot}\n onChangeText={(text) => setShots((p) => ({ ...p, [s.sceneId]: text }))}\n editable={!running}\n multiline\n style={styles.shot}\n placeholderTextColor=\"#5A5A66\"\n />\n ) : null}\n {st?.state === 'failed' ? <Text style={styles.error}>{st.message}</Text> : null}\n </View>\n );\n })}\n </ScrollView>\n <Pressable\n onPress={start}\n disabled={!runAction || running || chosen.length === 0}\n style={[styles.run, (!runAction || running || chosen.length === 0) && styles.runOff]}\n accessibilityRole=\"button\"\n >\n {running ? (\n <ActivityIndicator color=\"#0A0A0C\" />\n ) : (\n <Text style={styles.runLabel}>Film {produceSummary(chosen, DURATIONS)}</Text>\n )}\n </Pressable>\n </View>\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n scrim: { flex: 1, backgroundColor: 'rgba(0,0,0,0.45)' },\n sheet: {\n maxHeight: '82%',\n backgroundColor: '#141418',\n borderTopLeftRadius: 18,\n borderTopRightRadius: 18,\n paddingHorizontal: 16,\n paddingBottom: 28,\n gap: 10,\n },\n header: { flexDirection: 'row', alignItems: 'center', paddingTop: 14 },\n title: { flex: 1, color: '#F7F7FA', fontSize: 16, fontWeight: '700' },\n hint: { color: '#8B8B96', fontSize: 12.5, lineHeight: 17 },\n list: { gap: 8, paddingVertical: 6 },\n row: { gap: 6, padding: 10, borderRadius: 12, backgroundColor: '#1B1B21' },\n rowOn: { borderWidth: 1, borderColor: '#3B3366' },\n rowHead: { flexDirection: 'row', alignItems: 'center', gap: 8 },\n label: { flex: 1, color: '#F7F7FA', fontSize: 13.5, fontWeight: '600' },\n meta: { color: '#8B8B96', fontSize: 12 },\n shot: {\n color: '#E4E4EA',\n fontSize: 12.5,\n minHeight: 48,\n padding: 8,\n borderRadius: 8,\n backgroundColor: '#24242B',\n textAlignVertical: 'top',\n },\n error: { color: '#F87171', fontSize: 12 },\n run: { alignItems: 'center', paddingVertical: 13, borderRadius: 12, backgroundColor: '#8B7CFF' },\n runOff: { opacity: 0.4 },\n runLabel: { color: '#0A0A0C', fontSize: 14, fontWeight: '700' },\n});\n"],"names":["_a"],"mappings":"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"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import {generationMediaUrl}from'../mediaActions.js';import {buildVideoGenerateParams}from'../../generationModels.js';import {probeDuration}from'../renderTimeline.js';import {sceneLengthSec}from'../sceneLayers.js';var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
const PRODUCE_CONCURRENCY = 2;
|
|
21
|
+
const r1 = (v) => Math.round(v * 10) / 10;
|
|
22
|
+
function sceneCopy(timeline, sceneId) {
|
|
23
|
+
return timeline.texts.filter((t) => t.sceneId === sceneId && t.text.trim()).sort((a, b) => a.y - b.y || a.startSec - b.startSec).map((t) => t.text.replace(/\s+/g, " ").trim()).join(" / ");
|
|
24
|
+
}
|
|
25
|
+
function fallbackShot(timeline, scene) {
|
|
26
|
+
var _a;
|
|
27
|
+
const copy = sceneCopy(timeline, scene.id);
|
|
28
|
+
const beat = ((_a = scene.name) == null ? void 0 : _a.trim()) && !/^(scene|blank scene)\b/i.test(scene.name.trim()) ? scene.name.trim() : "";
|
|
29
|
+
const about = [beat, copy && `the moment behind "${copy}"`].filter(Boolean).join(": ");
|
|
30
|
+
return `Cinematic footage${about ? ` of ${about}` : ""}. Natural light, slow camera move, shallow depth of field. No text, captions or logos on screen.`;
|
|
31
|
+
}
|
|
32
|
+
function produceScenes(timeline, sourceSec = {}) {
|
|
33
|
+
return timeline.clips.map((clip, i) => {
|
|
34
|
+
var _a, _b, _c, _d, _e;
|
|
35
|
+
return {
|
|
36
|
+
sceneId: clip.id,
|
|
37
|
+
label: `#${i + 1} ${((_a = clip.name) == null ? void 0 : _a.trim()) || "Scene"}`,
|
|
38
|
+
seconds: r1(sceneLengthSec(clip, sourceSec[clip.id])),
|
|
39
|
+
holdSeconds: ((_d = (_c = (_b = timeline.clips[i + 1]) == null ? void 0 : _b.transitionIn) == null ? void 0 : _c.durationMs) != null ? _d : 0) / 1e3,
|
|
40
|
+
shot: ((_e = clip.shot) == null ? void 0 : _e.trim()) || fallbackShot(timeline, clip),
|
|
41
|
+
hasFootage: !clip.fillColor
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function orderSeconds(scene, options) {
|
|
46
|
+
var _a, _b;
|
|
47
|
+
const sorted = [...options].filter((n) => n > 0).sort((a, b) => a - b);
|
|
48
|
+
if (sorted.length === 0) return void 0;
|
|
49
|
+
return (_b = (_a = sorted.find((n) => n >= scene.seconds + scene.holdSeconds)) != null ? _a : sorted.find((n) => n >= scene.seconds)) != null ? _b : sorted[sorted.length - 1];
|
|
50
|
+
}
|
|
51
|
+
function fillSpeed(sceneSeconds, clipSeconds) {
|
|
52
|
+
if (clipSeconds >= sceneSeconds || sceneSeconds <= 0 || clipSeconds <= 0) return 1;
|
|
53
|
+
return Math.floor(clipSeconds / sceneSeconds * 1e3) / 1e3;
|
|
54
|
+
}
|
|
55
|
+
function sceneFootagePatch(scene, footage, sourceSec) {
|
|
56
|
+
var _a;
|
|
57
|
+
const window = sceneLengthSec(scene, sourceSec);
|
|
58
|
+
const speed = fillSpeed(window, footage.sourceSec);
|
|
59
|
+
const trimEndSec = Math.min(footage.sourceSec, Math.round(window * speed * 1e3) / 1e3);
|
|
60
|
+
return __spreadValues({
|
|
61
|
+
type: "video",
|
|
62
|
+
src: footage.src,
|
|
63
|
+
durationSec: null,
|
|
64
|
+
trimStartSec: 0,
|
|
65
|
+
trimEndSec,
|
|
66
|
+
// Not one of the preview presets; the render applies any factor.
|
|
67
|
+
speed,
|
|
68
|
+
muted: true,
|
|
69
|
+
fillColor: null,
|
|
70
|
+
kenBurns: null
|
|
71
|
+
}, ((_a = footage.shot) == null ? void 0 : _a.trim()) ? {
|
|
72
|
+
shot: footage.shot.trim()
|
|
73
|
+
} : {});
|
|
74
|
+
}
|
|
75
|
+
function produceJob(scene, durations, shot = scene.shot) {
|
|
76
|
+
return {
|
|
77
|
+
sceneId: scene.sceneId,
|
|
78
|
+
label: scene.label,
|
|
79
|
+
shot,
|
|
80
|
+
durationSeconds: orderSeconds(scene, durations)
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function produceSummary(scenes, options) {
|
|
84
|
+
const total = scenes.reduce((n, s) => {
|
|
85
|
+
var _a;
|
|
86
|
+
return n + ((_a = orderSeconds(s, options)) != null ? _a : s.seconds);
|
|
87
|
+
}, 0);
|
|
88
|
+
return `${scenes.length} clip${scenes.length === 1 ? "" : "s"} \xB7 ${Math.round(total)}s of video`;
|
|
89
|
+
}
|
|
90
|
+
function shotFailureMessage(error) {
|
|
91
|
+
var _a, _b;
|
|
92
|
+
const raw = String((_b = (_a = error == null ? void 0 : error.message) != null ? _a : error) != null ? _b : "");
|
|
93
|
+
if (/billing budget|spend limit|budget[^\n]*exhausted|insufficient credits|quota/i.test(raw)) {
|
|
94
|
+
return "Your plan's budget for this period is used up.";
|
|
95
|
+
}
|
|
96
|
+
if (/timed? ?out|deadline exceeded/i.test(raw)) return "The model took too long. Try again.";
|
|
97
|
+
if (/safety|moderation|content (policy|filter)|refused|not allowed/i.test(raw)) {
|
|
98
|
+
return "The model would not film this shot. Reword it and try again.";
|
|
99
|
+
}
|
|
100
|
+
return "This shot did not come back. Try again.";
|
|
101
|
+
}
|
|
102
|
+
async function runProduce(jobs, run, {
|
|
103
|
+
aspectRatio,
|
|
104
|
+
model,
|
|
105
|
+
concurrency = PRODUCE_CONCURRENCY,
|
|
106
|
+
onStatus
|
|
107
|
+
}) {
|
|
108
|
+
jobs.forEach((j) => onStatus(j.sceneId, {
|
|
109
|
+
state: "queued"
|
|
110
|
+
}));
|
|
111
|
+
let next = 0;
|
|
112
|
+
const worker = async () => {
|
|
113
|
+
var _a, _b;
|
|
114
|
+
while (next < jobs.length) {
|
|
115
|
+
const job = jobs[next++];
|
|
116
|
+
onStatus(job.sceneId, {
|
|
117
|
+
state: "filming"
|
|
118
|
+
});
|
|
119
|
+
try {
|
|
120
|
+
const raw = await run("yantra-video-generation", "YANTRA_VIDEO_GENERATION_GENERATE", buildVideoGenerateParams(__spreadProps(__spreadValues(__spreadValues({
|
|
121
|
+
prompt: job.shot,
|
|
122
|
+
aspectRatio
|
|
123
|
+
}, model ? {
|
|
124
|
+
model
|
|
125
|
+
} : {}), job.durationSeconds ? {
|
|
126
|
+
durationSeconds: job.durationSeconds
|
|
127
|
+
} : {}), {
|
|
128
|
+
generateAudio: false
|
|
129
|
+
})));
|
|
130
|
+
if (raw.successful === false) throw new Error(String(raw.error || "Generation failed"));
|
|
131
|
+
const src = generationMediaUrl(raw);
|
|
132
|
+
let sourceSec = (_a = job.durationSeconds) != null ? _a : 0;
|
|
133
|
+
try {
|
|
134
|
+
sourceSec = (_b = probeDuration(await run("yantra-video-editing", "YANTRA_VIDEO_EDIT_PROBE", {
|
|
135
|
+
input_url: src
|
|
136
|
+
}))) != null ? _b : sourceSec;
|
|
137
|
+
} catch (e) {
|
|
138
|
+
}
|
|
139
|
+
onStatus(job.sceneId, {
|
|
140
|
+
state: "done",
|
|
141
|
+
footage: {
|
|
142
|
+
src,
|
|
143
|
+
sourceSec: sourceSec || 8,
|
|
144
|
+
shot: job.shot
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
} catch (err) {
|
|
148
|
+
onStatus(job.sceneId, {
|
|
149
|
+
state: "failed",
|
|
150
|
+
message: shotFailureMessage(err)
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
await Promise.all(Array.from({
|
|
156
|
+
length: Math.max(1, Math.min(concurrency, jobs.length))
|
|
157
|
+
}, worker));
|
|
158
|
+
}export{PRODUCE_CONCURRENCY,fallbackShot,fillSpeed,orderSeconds,produceJob,produceScenes,produceSummary,runProduce,sceneFootagePatch,shotFailureMessage};//# sourceMappingURL=produceScenes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"produceScenes.js","sources":["../../../../../src/features/canvas/videoEditor/produce/produceScenes.ts"],"sourcesContent":["/**\n * Produce video: film every colour scene of a designed cut with an AI video\n * model - native twin of web editors/video-editor/produce/produceScenes.ts.\n *\n * A designed promo arrives as flat colour scenes with titles on them; each\n * scene carries a `shot` (what to film for its beat). Producing a scene\n * swaps its colour for the generated clip: the scene's window, its layers\n * and its transition stay put. The planning is pure and tested; `runProduce`\n * drives the generations with limited concurrency.\n */\nimport { generationMediaUrl, type RunMediaAction } from '../mediaActions';\nimport { buildVideoGenerateParams } from '../../generationModels';\nimport type { EditorClip, EditorTimeline, SpeedPreset } from '../editorModel';\nimport { probeDuration } from '../renderTimeline';\nimport { sceneLengthSec } from '../sceneLayers';\n\nexport interface ProduceScene {\n sceneId: string;\n /** \"#2 Dining room\" */\n label: string;\n /** Scene length on the timeline, seconds. */\n seconds: number;\n /** The crossfade into the next scene: the clip should run that much past the cut. */\n holdSeconds: number;\n /** What to film: the scene's own shot, else one written from its copy. */\n shot: string;\n /** Already footage (not a colour scene). */\n hasFootage: boolean;\n}\n\nexport interface SceneFootage {\n src: string;\n /** Measured length of the generated clip, seconds. */\n sourceSec: number;\n shot?: string;\n}\n\n/** Below this a slowed clip reads as slow motion; the sheet says so. */\nexport const SLOW_FILL_SPEED = 0.6;\n/** Generations in flight at once. */\nexport const PRODUCE_CONCURRENCY = 2;\n\nconst r1 = (v: number) => Math.round(v * 10) / 10;\n\n/** A scene's titles, top to bottom, as one line. */\nfunction sceneCopy(timeline: EditorTimeline, sceneId: string): string {\n return timeline.texts\n .filter((t) => t.sceneId === sceneId && t.text.trim())\n .sort((a, b) => a.y - b.y || a.startSec - b.startSec)\n .map((t) => t.text.replace(/\\s+/g, ' ').trim())\n .join(' / ');\n}\n\n/** A shot for a scene the design step never wrote one for: picture only, so titles are not painted twice. */\nexport function fallbackShot(timeline: EditorTimeline, scene: EditorClip): string {\n const copy = sceneCopy(timeline, scene.id);\n const beat = scene.name?.trim() && !/^(scene|blank scene)\\b/i.test(scene.name.trim()) ? scene.name.trim() : '';\n const about = [beat, copy && `the moment behind \"${copy}\"`].filter(Boolean).join(': ');\n return `Cinematic footage${about ? ` of ${about}` : ''}. Natural light, slow camera move, shallow depth of field. No text, captions or logos on screen.`;\n}\n\n/** The cut's scenes in play order, as the Produce sheet offers them. */\nexport function produceScenes(\n timeline: EditorTimeline,\n sourceSec: Readonly<Record<string, number>> = {},\n): ProduceScene[] {\n return timeline.clips.map((clip, i) => ({\n sceneId: clip.id,\n label: `#${i + 1} ${clip.name?.trim() || 'Scene'}`,\n seconds: r1(sceneLengthSec(clip, sourceSec[clip.id])),\n holdSeconds: (timeline.clips[i + 1]?.transitionIn?.durationMs ?? 0) / 1000,\n shot: clip.shot?.trim() || fallbackShot(timeline, clip),\n hasFootage: !clip.fillColor,\n }));\n}\n\n/**\n * Clip length to order: the shortest offered that covers scene + crossfade,\n * else the shortest that covers the scene, else the longest offered.\n * Undefined when the model offers no choice.\n */\nexport function orderSeconds(\n scene: Pick<ProduceScene, 'seconds' | 'holdSeconds'>,\n options: readonly number[],\n): number | undefined {\n const sorted = [...options].filter((n) => n > 0).sort((a, b) => a - b);\n if (sorted.length === 0) return undefined;\n return (\n sorted.find((n) => n >= scene.seconds + scene.holdSeconds) ??\n sorted.find((n) => n >= scene.seconds) ??\n sorted[sorted.length - 1]\n );\n}\n\n/** How fast a clip plays to fill its scene: 1 when it covers it; never clamped (a short clip would end the cut early). */\nexport function fillSpeed(sceneSeconds: number, clipSeconds: number): number {\n if (clipSeconds >= sceneSeconds || sceneSeconds <= 0 || clipSeconds <= 0) return 1;\n return Math.floor((clipSeconds / sceneSeconds) * 1000) / 1000;\n}\n\n/**\n * The colour scene turned into its footage: same window on the timeline (so\n * layers and later scenes do not move), cut from the start, slowed when\n * short; sound off (a promo has one bed). Frames past the window stay in the\n * source for the transition hold - the editor records `sourceSec` for it.\n */\nexport function sceneFootagePatch(scene: EditorClip, footage: SceneFootage, sourceSec?: number): Partial<EditorClip> {\n const window = sceneLengthSec(scene, sourceSec);\n const speed = fillSpeed(window, footage.sourceSec);\n const trimEndSec = Math.min(footage.sourceSec, Math.round(window * speed * 1000) / 1000);\n return {\n type: 'video',\n src: footage.src,\n durationSec: null,\n trimStartSec: 0,\n trimEndSec,\n // Not one of the preview presets; the render applies any factor.\n speed: speed as SpeedPreset,\n muted: true,\n fillColor: null,\n kenBurns: null,\n ...(footage.shot?.trim() ? { shot: footage.shot.trim() } : {}),\n };\n}\n\nexport interface ProduceJob {\n sceneId: string;\n label: string;\n shot: string;\n durationSeconds?: number;\n}\n\nexport function produceJob(scene: ProduceScene, durations: readonly number[], shot = scene.shot): ProduceJob {\n return { sceneId: scene.sceneId, label: scene.label, shot, durationSeconds: orderSeconds(scene, durations) };\n}\n\n/** \"4 clips · 30s of video\" */\nexport function produceSummary(\n scenes: readonly Pick<ProduceScene, 'seconds' | 'holdSeconds'>[],\n options: readonly number[],\n): string {\n const total = scenes.reduce((n, s) => n + (orderSeconds(s, options) ?? s.seconds), 0);\n return `${scenes.length} clip${scenes.length === 1 ? '' : 's'} · ${Math.round(total)}s of video`;\n}\n\n/** A shot failure in the sheet's own words (connector text is for logs). */\nexport function shotFailureMessage(error: unknown): string {\n const raw = String((error as { message?: string } | null)?.message ?? error ?? '');\n if (/billing budget|spend limit|budget[^\\n]*exhausted|insufficient credits|quota/i.test(raw)) {\n return \"Your plan's budget for this period is used up.\";\n }\n if (/timed? ?out|deadline exceeded/i.test(raw)) return 'The model took too long. Try again.';\n if (/safety|moderation|content (policy|filter)|refused|not allowed/i.test(raw)) {\n return 'The model would not film this shot. Reword it and try again.';\n }\n return 'This shot did not come back. Try again.';\n}\n\nexport type ProduceStatus =\n | { state: 'queued' }\n | { state: 'filming' }\n | { state: 'done'; footage: SceneFootage }\n | { state: 'failed'; message: string };\n\n/**\n * Film every job, at most `concurrency` at a time, reporting each scene's\n * status as it changes. A finished clip is probed for its real length (the\n * ordered length when the probe cannot tell). Never throws: a failed shot is\n * a `failed` status.\n */\nexport async function runProduce(\n jobs: readonly ProduceJob[],\n run: RunMediaAction,\n {\n aspectRatio,\n model,\n concurrency = PRODUCE_CONCURRENCY,\n onStatus,\n }: {\n aspectRatio: string;\n model?: string;\n concurrency?: number;\n onStatus: (sceneId: string, status: ProduceStatus) => void;\n },\n): Promise<void> {\n jobs.forEach((j) => onStatus(j.sceneId, { state: 'queued' }));\n let next = 0;\n const worker = async () => {\n while (next < jobs.length) {\n const job = jobs[next++];\n onStatus(job.sceneId, { state: 'filming' });\n try {\n const raw = await run(\n 'yantra-video-generation',\n 'YANTRA_VIDEO_GENERATION_GENERATE',\n buildVideoGenerateParams({\n prompt: job.shot,\n aspectRatio,\n ...(model ? { model } : {}),\n ...(job.durationSeconds ? { durationSeconds: job.durationSeconds } : {}),\n generateAudio: false,\n }),\n );\n if (raw.successful === false) throw new Error(String(raw.error || 'Generation failed'));\n const src = generationMediaUrl(raw);\n let sourceSec = job.durationSeconds ?? 0;\n try {\n sourceSec =\n probeDuration(\n await run('yantra-video-editing', 'YANTRA_VIDEO_EDIT_PROBE', { input_url: src }),\n ) ?? sourceSec;\n } catch {\n // The ordered length stands in.\n }\n onStatus(job.sceneId, { state: 'done', footage: { src, sourceSec: sourceSec || 8, shot: job.shot } });\n } catch (err) {\n onStatus(job.sceneId, { state: 'failed', message: shotFailureMessage(err) });\n }\n }\n };\n await Promise.all(Array.from({ length: Math.max(1, Math.min(concurrency, jobs.length)) }, worker));\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -46,17 +46,21 @@ function parseTokenResult(joined) {
|
|
|
46
46
|
const brace = joined.indexOf("{");
|
|
47
47
|
return brace >= 0 ? parse(joined.slice(brace)) : null;
|
|
48
48
|
}
|
|
49
|
+
const ACCEPTS_JOB = "__acceptsJob";
|
|
50
|
+
function runActionAcceptsJob(run) {
|
|
51
|
+
return typeof run === "function" && run[ACCEPTS_JOB] === true;
|
|
52
|
+
}
|
|
49
53
|
async function execAction(agentEndpoint, backendGraphqlUrl, token, connector, action, params, options = {}) {
|
|
50
|
-
var _a, _b;
|
|
54
|
+
var _a, _b, _c;
|
|
51
55
|
const timeoutMs = (_a = options.timeoutMs) != null ? _a : OP_TIMEOUT_MS;
|
|
52
56
|
const credentialId = (_b = options.credentialId) == null ? void 0 : _b.trim();
|
|
53
|
-
const body = __spreadValues({
|
|
57
|
+
const body = __spreadValues(__spreadValues({
|
|
54
58
|
args: ["connector", "run", "-c", connector, "-a", action, ...credentialId ? ["--credential-id", credentialId] : [], "--params", JSON.stringify(params)],
|
|
55
59
|
stream: true,
|
|
56
60
|
timeout_ms: timeoutMs
|
|
57
61
|
}, backendGraphqlUrl ? {
|
|
58
62
|
backend_graphql_url: backendGraphqlUrl
|
|
59
|
-
} : {});
|
|
63
|
+
} : {}), (_c = options.extraBody) != null ? _c : {});
|
|
60
64
|
const controller = new AbortController();
|
|
61
65
|
const abortTimer = setTimeout(() => controller.abort(), timeoutMs + CLIENT_ABORT_GRACE_MS);
|
|
62
66
|
let resp;
|
|
@@ -112,7 +116,15 @@ async function execAction(agentEndpoint, backendGraphqlUrl, token, connector, ac
|
|
|
112
116
|
function createRemoteRunAction(token, indexUrl) {
|
|
113
117
|
const agent = deriveAgentEndpoint(indexUrl);
|
|
114
118
|
const backend = deriveBackendGraphqlUrl(indexUrl);
|
|
115
|
-
|
|
119
|
+
const run = (connector, action, params, extra) => execAction(agent, backend, token, connector, action, params, (extra == null ? void 0 : extra.job) ? {
|
|
120
|
+
extraBody: {
|
|
121
|
+
job: extra.job
|
|
122
|
+
}
|
|
123
|
+
} : {});
|
|
124
|
+
Object.defineProperty(run, ACCEPTS_JOB, {
|
|
125
|
+
value: true
|
|
126
|
+
});
|
|
127
|
+
return run;
|
|
116
128
|
}
|
|
117
129
|
function createRemoteConnectorExec(token, indexUrl) {
|
|
118
130
|
const agent = deriveAgentEndpoint(indexUrl);
|
|
@@ -157,4 +169,4 @@ function proxiedMediaUrl(indexUrl, uri) {
|
|
|
157
169
|
if (!uri || uri.includes("/v1/files/proxy")) return uri;
|
|
158
170
|
if (!/generativelanguage\.googleapis|googleusercontent\.com/i.test(uri)) return uri;
|
|
159
171
|
return `${deriveAgentEndpoint(indexUrl)}/v1/files/proxy?url=${encodeURIComponent(uri)}`;
|
|
160
|
-
}export{createAgentConnectorExec,createRemoteConnectorExec,createRemoteRunAction,createRemoteUploadMedia,deriveAgentEndpoint,deriveBackendGraphqlUrl,parseTokenResult,proxiedMediaUrl,unwrapProxyUrl};//# sourceMappingURL=remoteMediaClient.js.map
|
|
172
|
+
}export{createAgentConnectorExec,createRemoteConnectorExec,createRemoteRunAction,createRemoteUploadMedia,deriveAgentEndpoint,deriveBackendGraphqlUrl,parseTokenResult,proxiedMediaUrl,runActionAcceptsJob,unwrapProxyUrl};//# sourceMappingURL=remoteMediaClient.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteMediaClient.js","sources":["../../../../src/features/canvas/videoEditor/remoteMediaClient.ts"],"sourcesContent":["/**\n * REMOTE-SIDE media-connector client - the fallback that makes editors work\n * on app binaries that predate the host seams.\n *\n * The connector transport is plain fetch with a bearer the remote already\n * receives (the same system JWT the surface index accepts), so nothing here\n * needs the host: the agent endpoint and backend GraphQL URL derive from the\n * environment the indexUrl names (…cdebase.dev -> cdecli-agent.cdebase.dev,\n * …yantra.app -> cdecli-agent.yantra.app; surface-index-backend.X ->\n * ideback.X). A host-provided seam still wins when present - it can carry\n * better auth refresh - this only fills the gap.\n *\n * Transport contract == the hosts' clients (exec/stream body, data: frame\n * parsing, /v1/files/upload) - keep the three in lockstep.\n */\nimport type { RunMediaAction } from './mediaActions';\nimport { uploadFilenameFor } from './solidColorPng';\n\nconst OP_TIMEOUT_MS = 900_000; // clips (yantra-video-clip) is the long pole (~15 min)\n\nfunction indexHost(indexUrl: string): string {\n return indexUrl.replace(/^https?:\\/\\//, '').split('/')[0] ?? '';\n}\n\nexport function deriveAgentEndpoint(indexUrl: string): string {\n const host = indexHost(indexUrl);\n if (host.endsWith('.yantra.app')) return 'https://cdecli-agent.yantra.app';\n return 'https://cdecli-agent.cdebase.dev';\n}\n\nexport function deriveBackendGraphqlUrl(indexUrl: string): string | null {\n const host = indexHost(indexUrl);\n if (!host.startsWith('surface-index-backend.')) return null;\n return `https://ideback.${host.slice('surface-index-backend.'.length)}/graphql`;\n}\n\n/** Grace on top of the agent's own timeout before the phone gives up on the request. */\nconst CLIENT_ABORT_GRACE_MS = 30_000;\n\ninterface ExecFrame {\n type?: string;\n data?: unknown;\n error?: string;\n exit_code?: number;\n}\n\nconst RESULT_SENTINEL = '__CDECLI_RESULT__';\n\n/**\n * The action's JSON from streamed stdout when no `result` frame came. Connectors\n * wrap it as `__CDECLI_RESULT__{json}__CDECLI_RESULT__` after any progress text;\n * a bare object after progress text is the older form.\n */\nexport function parseTokenResult(joined: string): Record<string, unknown> | null {\n const parse = (text: string): Record<string, unknown> | null => {\n try {\n const value: unknown = JSON.parse(text);\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n } catch {\n return null;\n }\n };\n const end = joined.lastIndexOf(RESULT_SENTINEL);\n const start = end > 0 ? joined.lastIndexOf(RESULT_SENTINEL, end - 1) : -1;\n if (start >= 0) return parse(joined.slice(start + RESULT_SENTINEL.length, end));\n const brace = joined.indexOf('{');\n return brace >= 0 ? parse(joined.slice(brace)) : null;\n}\n\nexport interface RemoteExecOptions {\n /** Vault credential the action runs with (`--credential-id`), e.g. a connected mailbox. */\n credentialId?: string;\n /** Agent-side timeout; the request is aborted on the phone shortly after it. */\n timeoutMs?: number;\n}\n\nasync function execAction(\n agentEndpoint: string,\n backendGraphqlUrl: string | null,\n token: string,\n connector: string,\n action: string,\n params: Record<string, unknown>,\n options: RemoteExecOptions = {},\n): Promise<Record<string, unknown>> {\n const timeoutMs = options.timeoutMs ?? OP_TIMEOUT_MS;\n const credentialId = options.credentialId?.trim();\n const body = {\n args: [\n 'connector',\n 'run',\n '-c',\n connector,\n '-a',\n action,\n ...(credentialId ? ['--credential-id', credentialId] : []),\n '--params',\n JSON.stringify(params),\n ],\n stream: true,\n timeout_ms: timeoutMs,\n ...(backendGraphqlUrl ? { backend_graphql_url: backendGraphqlUrl } : {}),\n };\n // Without an abort a stalled agent leaves the caller waiting forever: the\n // screen keeps its spinner and nothing ever replaces it.\n const controller = new AbortController();\n const abortTimer = setTimeout(() => controller.abort(), timeoutMs + CLIENT_ABORT_GRACE_MS);\n let resp: Response;\n let text: string;\n try {\n resp = await fetch(`${agentEndpoint}/v1/cdecli/exec/stream`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${token}` },\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n text = await resp.text();\n } catch (err) {\n if (controller.signal.aborted) throw new Error(`${action} timed out`);\n throw err;\n } finally {\n clearTimeout(abortTimer);\n }\n if (!resp.ok) throw new Error(`${action} failed (HTTP ${resp.status}): ${text.slice(0, 200)}`);\n\n let result: Record<string, unknown> | null = null;\n let stderr = '';\n let exitCode: number | undefined;\n const jsonTokens: string[] = [];\n for (const rawLine of text.split('\\n')) {\n const line = rawLine.startsWith('data: ') ? rawLine.slice(6).trim() : rawLine.trim();\n if (!line) continue;\n let frame: ExecFrame;\n try {\n frame = JSON.parse(line) as ExecFrame;\n } catch {\n continue;\n }\n if (typeof frame.exit_code === 'number') exitCode = frame.exit_code;\n if (frame.error) stderr += frame.error;\n if (frame.type === 'result' && frame.data && typeof frame.data === 'object') {\n result = frame.data as Record<string, unknown>;\n } else if ((frame.type === 'stderr' || frame.type === 'error') && typeof frame.data === 'string') {\n stderr += frame.data;\n } else if (frame.type === 'token' && typeof frame.data === 'string') {\n jsonTokens.push(frame.data);\n }\n }\n if (!result) result = parseTokenResult(jsonTokens.join(''));\n if ((exitCode !== undefined && exitCode !== 0) || (!result && stderr)) {\n throw new Error(`${action} failed: ${stderr.slice(0, 300) || `exit ${exitCode}`}`);\n }\n if (!result) throw new Error(`${action} returned no result`);\n return result;\n}\n\n/** Connector runner from what the remote already holds - token + indexUrl. */\nexport function createRemoteRunAction(token: string, indexUrl: string): RunMediaAction {\n const agent = deriveAgentEndpoint(indexUrl);\n const backend = deriveBackendGraphqlUrl(indexUrl);\n return (connector, action, params) => execAction(agent, backend, token, connector, action, params);\n}\n\nexport type RemoteConnectorExec = (\n connector: string,\n action: string,\n params: Record<string, unknown>,\n options?: RemoteExecOptions,\n) => Promise<Record<string, unknown>>;\n\n/** Same transport as createRemoteRunAction, for any connector, with a credential and timeout per call. */\nexport function createRemoteConnectorExec(token: string, indexUrl: string): RemoteConnectorExec {\n const agent = deriveAgentEndpoint(indexUrl);\n const backend = deriveBackendGraphqlUrl(indexUrl);\n return (connector, action, params, options) =>\n execAction(agent, backend, token, connector, action, params, options);\n}\n\n/**\n * Same transport against an agent the caller names. The host knows the agent its own chat session talks to\n * (CDECLI_AGENT_ENDPOINT); a remote only has the index URL to derive one from. A call that must reach the same\n * per-user state the chat's agent works on (the person's Computer) goes there, with the token that session uses.\n */\nexport function createAgentConnectorExec(\n token: string,\n agentEndpoint: string,\n backendGraphqlUrl: string | null = null,\n): RemoteConnectorExec {\n const agent = agentEndpoint.trim().replace(/\\/+$/, '');\n return (connector, action, params, options) =>\n execAction(agent, backendGraphqlUrl, token, connector, action, params, options);\n}\n\n/** file:// -> store URL via the agent's upload endpoint. */\nexport function createRemoteUploadMedia(token: string, indexUrl: string): (localUri: string) => Promise<string> {\n const agent = deriveAgentEndpoint(indexUrl);\n return async (localUri: string) => {\n const blob = await (await fetch(localUri)).blob();\n const filename = uploadFilenameFor(localUri);\n const resp = await fetch(`${agent}/v1/files/upload?filename=${encodeURIComponent(filename)}`, {\n method: 'POST',\n headers: { 'content-type': blob.type || 'application/octet-stream', authorization: `Bearer ${token}` },\n body: blob,\n });\n if (!resp.ok) throw new Error(`Upload failed (HTTP ${resp.status}): ${(await resp.text()).slice(0, 160)}`);\n const result = (await resp.json()) as { url?: string };\n if (!result.url) throw new Error('Upload returned no URL');\n return result.url;\n };\n}\n\n/**\n * Twin of web canvas `unwrapProxyUrl`: the connector fetches the reference\n * server-side, so pass the inner Google/store URL, not the agent proxy wrap.\n */\nexport function unwrapProxyUrl(src: string): string {\n try {\n const u = new URL(src);\n if (u.pathname.includes('/v1/files/proxy')) {\n const inner = u.searchParams.get('url');\n if (inner) return inner;\n }\n } catch {\n /* not a URL */\n }\n return src;\n}\n\n/** Google Veo URIs are not fetchable on device — route them through the agent proxy. */\nexport function proxiedMediaUrl(indexUrl: string, uri: string): string {\n if (!uri || uri.includes('/v1/files/proxy')) return uri;\n if (!/generativelanguage\\.googleapis|googleusercontent\\.com/i.test(uri)) return uri;\n return `${deriveAgentEndpoint(indexUrl)}/v1/files/proxy?url=${encodeURIComponent(uri)}`;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAiBA,MAAM,aAAgB,GAAA,GAAA;AAEtB,SAAS,UAAU,QAA0B,EAAA;AAnB7C,EAAA,IAAA,EAAA;AAoBE,EAAO,OAAA,CAAA,EAAA,GAAA,QAAA,CAAS,OAAQ,CAAA,cAAA,EAAgB,EAAE,CAAA,CAAE,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,KAAjD,IAAsD,GAAA,EAAA,GAAA,EAAA;AAC/D;AACO,SAAS,oBAAoB,QAA0B,EAAA;AAC5D,EAAM,MAAA,IAAA,GAAO,UAAU,QAAQ,CAAA;AAC/B,EAAA,IAAI,IAAK,CAAA,QAAA,CAAS,aAAa,CAAA,EAAU,OAAA,iCAAA;AACzC,EAAO,OAAA,kCAAA;AACT;AACO,SAAS,wBAAwB,QAAiC,EAAA;AACvE,EAAM,MAAA,IAAA,GAAO,UAAU,QAAQ,CAAA;AAC/B,EAAA,IAAI,CAAC,IAAA,CAAK,UAAW,CAAA,wBAAwB,GAAU,OAAA,IAAA;AACvD,EAAA,OAAO,CAAmB,gBAAA,EAAA,IAAA,CAAK,KAAM,CAAA,wBAAA,CAAyB,MAAM,CAAC,CAAA,QAAA,CAAA;AACvE;AAGA,MAAM,qBAAwB,GAAA,GAAA;AAO9B,MAAM,eAAkB,GAAA,mBAAA;AAOjB,SAAS,iBAAiB,MAAgD,EAAA;AAC/E,EAAM,MAAA,KAAA,GAAQ,CAAC,IAAiD,KAAA;AAC9D,IAAI,IAAA;AACF,MAAM,MAAA,KAAA,GAAiB,IAAK,CAAA,KAAA,CAAM,IAAI,CAAA;AACtC,MAAO,OAAA,KAAA,IAAS,OAAO,KAAU,KAAA,QAAA,IAAY,CAAC,KAAM,CAAA,OAAA,CAAQ,KAAK,CAAA,GAAI,KAAmC,GAAA,IAAA;AAAA,KAClG,CAAA,OAAA,CAAA,EAAA;AACN,MAAO,OAAA,IAAA;AAAA;AACT,GACF;AACA,EAAM,MAAA,GAAA,GAAM,MAAO,CAAA,WAAA,CAAY,eAAe,CAAA;AAC9C,EAAM,MAAA,KAAA,GAAQ,MAAM,CAAI,GAAA,MAAA,CAAO,YAAY,eAAiB,EAAA,GAAA,GAAM,CAAC,CAAI,GAAA,EAAA;AACvE,EAAI,IAAA,KAAA,IAAS,CAAG,EAAA,OAAO,KAAM,CAAA,MAAA,CAAO,MAAM,KAAQ,GAAA,eAAA,CAAgB,MAAQ,EAAA,GAAG,CAAC,CAAA;AAC9E,EAAM,MAAA,KAAA,GAAQ,MAAO,CAAA,OAAA,CAAQ,GAAG,CAAA;AAChC,EAAA,OAAO,SAAS,CAAI,GAAA,KAAA,CAAM,OAAO,KAAM,CAAA,KAAK,CAAC,CAAI,GAAA,IAAA;AACnD;AAOA,eAAe,UAAA,CAAW,eAAuB,iBAAkC,EAAA,KAAA,EAAe,WAAmB,MAAgB,EAAA,MAAA,EAAiC,OAA6B,GAAA,EAAsC,EAAA;AArEzO,EAAA,IAAA,EAAA,EAAA,EAAA;AAsEE,EAAM,MAAA,SAAA,GAAA,CAAY,EAAQ,GAAA,OAAA,CAAA,SAAA,KAAR,IAAqB,GAAA,EAAA,GAAA,aAAA;AACvC,EAAM,MAAA,YAAA,GAAA,CAAe,EAAQ,GAAA,OAAA,CAAA,YAAA,KAAR,IAAsB,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,EAAA;AAC3C,EAAA,MAAM,IAAO,GAAA,cAAA,CAAA;AAAA,IACX,IAAA,EAAM,CAAC,WAAa,EAAA,KAAA,EAAO,MAAM,SAAW,EAAA,IAAA,EAAM,QAAQ,GAAI,YAAA,GAAe,CAAC,iBAAmB,EAAA,YAAY,IAAI,EAAC,EAAI,YAAY,IAAK,CAAA,SAAA,CAAU,MAAM,CAAC,CAAA;AAAA,IACxJ,MAAQ,EAAA,IAAA;AAAA,IACR,UAAY,EAAA;AAAA,GAAA,EACR,iBAAoB,GAAA;AAAA,IACtB,mBAAqB,EAAA;AAAA,MACnB,EAAC,CAAA;AAIP,EAAM,MAAA,UAAA,GAAa,IAAI,eAAgB,EAAA;AACvC,EAAA,MAAM,aAAa,UAAW,CAAA,MAAM,WAAW,KAAM,EAAA,EAAG,YAAY,qBAAqB,CAAA;AACzF,EAAI,IAAA,IAAA;AACJ,EAAI,IAAA,IAAA;AACJ,EAAI,IAAA;AACF,IAAA,IAAA,GAAO,MAAM,KAAA,CAAM,CAAG,EAAA,aAAa,CAA0B,sBAAA,CAAA,EAAA;AAAA,MAC3D,MAAQ,EAAA,MAAA;AAAA,MACR,OAAS,EAAA;AAAA,QACP,cAAgB,EAAA,kBAAA;AAAA,QAChB,aAAA,EAAe,UAAU,KAAK,CAAA;AAAA,OAChC;AAAA,MACA,IAAA,EAAM,IAAK,CAAA,SAAA,CAAU,IAAI,CAAA;AAAA,MACzB,QAAQ,UAAW,CAAA;AAAA,KACpB,CAAA;AACD,IAAO,IAAA,GAAA,MAAM,KAAK,IAAK,EAAA;AAAA,WAChB,GAAK,EAAA;AACZ,IAAI,IAAA,UAAA,CAAW,OAAO,OAAS,EAAA,MAAM,IAAI,KAAM,CAAA,CAAA,EAAG,MAAM,CAAY,UAAA,CAAA,CAAA;AACpE,IAAM,MAAA,GAAA;AAAA,GACN,SAAA;AACA,IAAA,YAAA,CAAa,UAAU,CAAA;AAAA;AAEzB,EAAA,IAAI,CAAC,IAAK,CAAA,EAAA,EAAU,MAAA,IAAI,MAAM,CAAG,EAAA,MAAM,CAAiB,cAAA,EAAA,IAAA,CAAK,MAAM,CAAM,GAAA,EAAA,IAAA,CAAK,MAAM,CAAG,EAAA,GAAG,CAAC,CAAE,CAAA,CAAA;AAC7F,EAAA,IAAI,MAAyC,GAAA,IAAA;AAC7C,EAAA,IAAI,MAAS,GAAA,EAAA;AACb,EAAI,IAAA,QAAA;AACJ,EAAA,MAAM,aAAuB,EAAC;AAC9B,EAAA,KAAA,MAAW,OAAW,IAAA,IAAA,CAAK,KAAM,CAAA,IAAI,CAAG,EAAA;AACtC,IAAA,MAAM,IAAO,GAAA,OAAA,CAAQ,UAAW,CAAA,QAAQ,CAAI,GAAA,OAAA,CAAQ,KAAM,CAAA,CAAC,CAAE,CAAA,IAAA,EAAS,GAAA,OAAA,CAAQ,IAAK,EAAA;AACnF,IAAA,IAAI,CAAC,IAAM,EAAA;AACX,IAAI,IAAA,KAAA;AACJ,IAAI,IAAA;AACF,MAAQ,KAAA,GAAA,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,KACjB,CAAA,OAAA,CAAA,EAAA;AACN,MAAA;AAAA;AAEF,IAAA,IAAI,OAAO,KAAA,CAAM,SAAc,KAAA,QAAA,aAAqB,KAAM,CAAA,SAAA;AAC1D,IAAI,IAAA,KAAA,CAAM,KAAO,EAAA,MAAA,IAAU,KAAM,CAAA,KAAA;AACjC,IAAI,IAAA,KAAA,CAAM,SAAS,QAAY,IAAA,KAAA,CAAM,QAAQ,OAAO,KAAA,CAAM,SAAS,QAAU,EAAA;AAC3E,MAAA,MAAA,GAAS,KAAM,CAAA,IAAA;AAAA,KACjB,MAAA,IAAA,CAAY,KAAM,CAAA,IAAA,KAAS,QAAY,IAAA,KAAA,CAAM,SAAS,OAAY,KAAA,OAAO,KAAM,CAAA,IAAA,KAAS,QAAU,EAAA;AAChG,MAAA,MAAA,IAAU,KAAM,CAAA,IAAA;AAAA,eACP,KAAM,CAAA,IAAA,KAAS,WAAW,OAAO,KAAA,CAAM,SAAS,QAAU,EAAA;AACnE,MAAW,UAAA,CAAA,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA;AAC5B;AAEF,EAAA,IAAI,CAAC,MAAQ,EAAA,MAAA,GAAS,iBAAiB,UAAW,CAAA,IAAA,CAAK,EAAE,CAAC,CAAA;AAC1D,EAAA,IAAI,aAAa,MAAa,IAAA,QAAA,KAAa,CAAK,IAAA,CAAC,UAAU,MAAQ,EAAA;AACjE,IAAA,MAAM,IAAI,KAAA,CAAM,CAAG,EAAA,MAAM,CAAY,SAAA,EAAA,MAAA,CAAO,KAAM,CAAA,CAAA,EAAG,GAAG,CAAA,IAAK,CAAQ,KAAA,EAAA,QAAQ,EAAE,CAAE,CAAA,CAAA;AAAA;AAEnF,EAAA,IAAI,CAAC,MAAQ,EAAA,MAAM,IAAI,KAAM,CAAA,CAAA,EAAG,MAAM,CAAqB,mBAAA,CAAA,CAAA;AAC3D,EAAO,OAAA,MAAA;AACT;AAGgB,SAAA,qBAAA,CAAsB,OAAe,QAAkC,EAAA;AACrF,EAAM,MAAA,KAAA,GAAQ,oBAAoB,QAAQ,CAAA;AAC1C,EAAM,MAAA,OAAA,GAAU,wBAAwB,QAAQ,CAAA;AAChD,EAAO,OAAA,CAAC,SAAW,EAAA,MAAA,EAAQ,MAAW,KAAA,UAAA,CAAW,OAAO,OAAS,EAAA,KAAA,EAAO,SAAW,EAAA,MAAA,EAAQ,MAAM,CAAA;AACnG;AAIgB,SAAA,yBAAA,CAA0B,OAAe,QAAuC,EAAA;AAC9F,EAAM,MAAA,KAAA,GAAQ,oBAAoB,QAAQ,CAAA;AAC1C,EAAM,MAAA,OAAA,GAAU,wBAAwB,QAAQ,CAAA;AAChD,EAAA,OAAO,CAAC,SAAA,EAAW,MAAQ,EAAA,MAAA,EAAQ,OAAY,KAAA,UAAA,CAAW,KAAO,EAAA,OAAA,EAAS,KAAO,EAAA,SAAA,EAAW,MAAQ,EAAA,MAAA,EAAQ,OAAO,CAAA;AACrH;AAOO,SAAS,wBAAyB,CAAA,KAAA,EAAe,aAAuB,EAAA,iBAAA,GAAmC,IAA2B,EAAA;AAC3I,EAAA,MAAM,QAAQ,aAAc,CAAA,IAAA,EAAO,CAAA,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACrD,EAAA,OAAO,CAAC,SAAA,EAAW,MAAQ,EAAA,MAAA,EAAQ,OAAY,KAAA,UAAA,CAAW,KAAO,EAAA,iBAAA,EAAmB,KAAO,EAAA,SAAA,EAAW,MAAQ,EAAA,MAAA,EAAQ,OAAO,CAAA;AAC/H;AAGgB,SAAA,uBAAA,CAAwB,OAAe,QAAyD,EAAA;AAC9G,EAAM,MAAA,KAAA,GAAQ,oBAAoB,QAAQ,CAAA;AAC1C,EAAA,OAAO,OAAO,QAAqB,KAAA;AACjC,IAAA,MAAM,OAAO,MAAO,CAAA,MAAM,KAAM,CAAA,QAAQ,GAAG,IAAK,EAAA;AAChD,IAAM,MAAA,QAAA,GAAW,kBAAkB,QAAQ,CAAA;AAC3C,IAAM,MAAA,IAAA,GAAO,MAAM,KAAM,CAAA,CAAA,EAAG,KAAK,CAA6B,0BAAA,EAAA,kBAAA,CAAmB,QAAQ,CAAC,CAAI,CAAA,EAAA;AAAA,MAC5F,MAAQ,EAAA,MAAA;AAAA,MACR,OAAS,EAAA;AAAA,QACP,cAAA,EAAgB,KAAK,IAAQ,IAAA,0BAAA;AAAA,QAC7B,aAAA,EAAe,UAAU,KAAK,CAAA;AAAA,OAChC;AAAA,MACA,IAAM,EAAA;AAAA,KACP,CAAA;AACD,IAAA,IAAI,CAAC,IAAK,CAAA,EAAA,QAAU,IAAI,KAAA,CAAM,uBAAuB,IAAK,CAAA,MAAM,CAAO,GAAA,EAAA,CAAA,MAAM,KAAK,IAAK,EAAA,EAAG,MAAM,CAAG,EAAA,GAAG,CAAC,CAAE,CAAA,CAAA;AACzG,IAAM,MAAA,MAAA,GAAU,MAAM,IAAA,CAAK,IAAK,EAAA;AAGhC,IAAA,IAAI,CAAC,MAAO,CAAA,GAAA,EAAW,MAAA,IAAI,MAAM,wBAAwB,CAAA;AACzD,IAAA,OAAO,MAAO,CAAA,GAAA;AAAA,GAChB;AACF;AAMO,SAAS,eAAe,GAAqB,EAAA;AAClD,EAAI,IAAA;AACF,IAAM,MAAA,CAAA,GAAI,IAAI,GAAA,CAAI,GAAG,CAAA;AACrB,IAAA,IAAI,CAAE,CAAA,QAAA,CAAS,QAAS,CAAA,iBAAiB,CAAG,EAAA;AAC1C,MAAA,MAAM,KAAQ,GAAA,CAAA,CAAE,YAAa,CAAA,GAAA,CAAI,KAAK,CAAA;AACtC,MAAA,IAAI,OAAc,OAAA,KAAA;AAAA;AACpB,GACM,CAAA,OAAA,CAAA,EAAA;AAAA;AAGR,EAAO,OAAA,GAAA;AACT;AAGgB,SAAA,eAAA,CAAgB,UAAkB,GAAqB,EAAA;AACrE,EAAA,IAAI,CAAC,GAAO,IAAA,GAAA,CAAI,QAAS,CAAA,iBAAiB,GAAU,OAAA,GAAA;AACpD,EAAA,IAAI,CAAC,wDAAA,CAAyD,IAAK,CAAA,GAAG,GAAU,OAAA,GAAA;AAChF,EAAA,OAAO,GAAG,mBAAoB,CAAA,QAAQ,CAAC,CAAuB,oBAAA,EAAA,kBAAA,CAAmB,GAAG,CAAC,CAAA,CAAA;AACvF"}
|
|
1
|
+
{"version":3,"file":"remoteMediaClient.js","sources":["../../../../src/features/canvas/videoEditor/remoteMediaClient.ts"],"sourcesContent":["/**\n * REMOTE-SIDE media-connector client - the fallback that makes editors work\n * on app binaries that predate the host seams.\n *\n * The connector transport is plain fetch with a bearer the remote already\n * receives (the same system JWT the surface index accepts), so nothing here\n * needs the host: the agent endpoint and backend GraphQL URL derive from the\n * environment the indexUrl names (…cdebase.dev -> cdecli-agent.cdebase.dev,\n * …yantra.app -> cdecli-agent.yantra.app; surface-index-backend.X ->\n * ideback.X). A host-provided seam still wins when present - it can carry\n * better auth refresh - this only fills the gap.\n *\n * Transport contract == the hosts' clients (exec/stream body, data: frame\n * parsing, /v1/files/upload) - keep the three in lockstep.\n */\nimport type { RunMediaAction } from './mediaActions';\nimport { uploadFilenameFor } from './solidColorPng';\n\nconst OP_TIMEOUT_MS = 900_000; // clips (yantra-video-clip) is the long pole (~15 min)\n\nfunction indexHost(indexUrl: string): string {\n return indexUrl.replace(/^https?:\\/\\//, '').split('/')[0] ?? '';\n}\n\nexport function deriveAgentEndpoint(indexUrl: string): string {\n const host = indexHost(indexUrl);\n if (host.endsWith('.yantra.app')) return 'https://cdecli-agent.yantra.app';\n return 'https://cdecli-agent.cdebase.dev';\n}\n\nexport function deriveBackendGraphqlUrl(indexUrl: string): string | null {\n const host = indexHost(indexUrl);\n if (!host.startsWith('surface-index-backend.')) return null;\n return `https://ideback.${host.slice('surface-index-backend.'.length)}/graphql`;\n}\n\n/** Grace on top of the agent's own timeout before the phone gives up on the request. */\nconst CLIENT_ABORT_GRACE_MS = 30_000;\n\ninterface ExecFrame {\n type?: string;\n data?: unknown;\n error?: string;\n exit_code?: number;\n}\n\nconst RESULT_SENTINEL = '__CDECLI_RESULT__';\n\n/**\n * The action's JSON from streamed stdout when no `result` frame came. Connectors\n * wrap it as `__CDECLI_RESULT__{json}__CDECLI_RESULT__` after any progress text;\n * a bare object after progress text is the older form.\n */\nexport function parseTokenResult(joined: string): Record<string, unknown> | null {\n const parse = (text: string): Record<string, unknown> | null => {\n try {\n const value: unknown = JSON.parse(text);\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n } catch {\n return null;\n }\n };\n const end = joined.lastIndexOf(RESULT_SENTINEL);\n const start = end > 0 ? joined.lastIndexOf(RESULT_SENTINEL, end - 1) : -1;\n if (start >= 0) return parse(joined.slice(start + RESULT_SENTINEL.length, end));\n const brace = joined.indexOf('{');\n return brace >= 0 ? parse(joined.slice(brace)) : null;\n}\n\nexport interface RemoteExecOptions {\n /** Vault credential the action runs with (`--credential-id`), e.g. a connected mailbox. */\n credentialId?: string;\n /** Agent-side timeout; the request is aborted on the phone shortly after it. */\n timeoutMs?: number;\n /**\n * Extra top-level fields for the exec body - `job` (the surface job this\n * call runs, see ../serverTasks): the agent reports the job's verdict to\n * its server row. An older agent ignores it.\n */\n extraBody?: Record<string, unknown>;\n}\n\n/** What a caller may add to one exec request. */\nexport interface ExecExtraBody {\n job?: unknown;\n}\n\n/** A RunMediaAction that can carry extra exec-body fields (`job`). */\nexport type RunMediaActionWithBody = (\n connector: Parameters<RunMediaAction>[0],\n action: string,\n params: Record<string, unknown>,\n extra?: ExecExtraBody,\n) => Promise<Record<string, unknown>>;\n\nconst ACCEPTS_JOB = '__acceptsJob';\n\n/** True for runners built here, which put `extra.job` on the exec body; a host seam may not. */\nexport function runActionAcceptsJob(run: unknown): run is RunMediaActionWithBody {\n return typeof run === 'function' && (run as unknown as Record<string, unknown>)[ACCEPTS_JOB] === true;\n}\n\nasync function execAction(\n agentEndpoint: string,\n backendGraphqlUrl: string | null,\n token: string,\n connector: string,\n action: string,\n params: Record<string, unknown>,\n options: RemoteExecOptions = {},\n): Promise<Record<string, unknown>> {\n const timeoutMs = options.timeoutMs ?? OP_TIMEOUT_MS;\n const credentialId = options.credentialId?.trim();\n const body = {\n args: [\n 'connector',\n 'run',\n '-c',\n connector,\n '-a',\n action,\n ...(credentialId ? ['--credential-id', credentialId] : []),\n '--params',\n JSON.stringify(params),\n ],\n stream: true,\n timeout_ms: timeoutMs,\n ...(backendGraphqlUrl ? { backend_graphql_url: backendGraphqlUrl } : {}),\n ...(options.extraBody ?? {}),\n };\n // Without an abort a stalled agent leaves the caller waiting forever: the\n // screen keeps its spinner and nothing ever replaces it.\n const controller = new AbortController();\n const abortTimer = setTimeout(() => controller.abort(), timeoutMs + CLIENT_ABORT_GRACE_MS);\n let resp: Response;\n let text: string;\n try {\n resp = await fetch(`${agentEndpoint}/v1/cdecli/exec/stream`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${token}` },\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n text = await resp.text();\n } catch (err) {\n if (controller.signal.aborted) throw new Error(`${action} timed out`);\n throw err;\n } finally {\n clearTimeout(abortTimer);\n }\n if (!resp.ok) throw new Error(`${action} failed (HTTP ${resp.status}): ${text.slice(0, 200)}`);\n\n let result: Record<string, unknown> | null = null;\n let stderr = '';\n let exitCode: number | undefined;\n const jsonTokens: string[] = [];\n for (const rawLine of text.split('\\n')) {\n const line = rawLine.startsWith('data: ') ? rawLine.slice(6).trim() : rawLine.trim();\n if (!line) continue;\n let frame: ExecFrame;\n try {\n frame = JSON.parse(line) as ExecFrame;\n } catch {\n continue;\n }\n if (typeof frame.exit_code === 'number') exitCode = frame.exit_code;\n if (frame.error) stderr += frame.error;\n if (frame.type === 'result' && frame.data && typeof frame.data === 'object') {\n result = frame.data as Record<string, unknown>;\n } else if ((frame.type === 'stderr' || frame.type === 'error') && typeof frame.data === 'string') {\n stderr += frame.data;\n } else if (frame.type === 'token' && typeof frame.data === 'string') {\n jsonTokens.push(frame.data);\n }\n }\n if (!result) result = parseTokenResult(jsonTokens.join(''));\n if ((exitCode !== undefined && exitCode !== 0) || (!result && stderr)) {\n throw new Error(`${action} failed: ${stderr.slice(0, 300) || `exit ${exitCode}`}`);\n }\n if (!result) throw new Error(`${action} returned no result`);\n return result;\n}\n\n/** Connector runner from what the remote already holds - token + indexUrl. */\nexport function createRemoteRunAction(token: string, indexUrl: string): RunMediaAction {\n const agent = deriveAgentEndpoint(indexUrl);\n const backend = deriveBackendGraphqlUrl(indexUrl);\n // The optional 4th argument is invisible to RunMediaAction callers, so every existing call is unchanged.\n const run: RunMediaActionWithBody = (connector, action, params, extra) =>\n execAction(\n agent,\n backend,\n token,\n connector,\n action,\n params,\n extra?.job ? { extraBody: { job: extra.job } } : {},\n );\n Object.defineProperty(run, ACCEPTS_JOB, { value: true });\n return run;\n}\n\nexport type RemoteConnectorExec = (\n connector: string,\n action: string,\n params: Record<string, unknown>,\n options?: RemoteExecOptions,\n) => Promise<Record<string, unknown>>;\n\n/** Same transport as createRemoteRunAction, for any connector, with a credential and timeout per call. */\nexport function createRemoteConnectorExec(token: string, indexUrl: string): RemoteConnectorExec {\n const agent = deriveAgentEndpoint(indexUrl);\n const backend = deriveBackendGraphqlUrl(indexUrl);\n return (connector, action, params, options) =>\n execAction(agent, backend, token, connector, action, params, options);\n}\n\n/**\n * Same transport against an agent the caller names. The host knows the agent its own chat session talks to\n * (CDECLI_AGENT_ENDPOINT); a remote only has the index URL to derive one from. A call that must reach the same\n * per-user state the chat's agent works on (the person's Computer) goes there, with the token that session uses.\n */\nexport function createAgentConnectorExec(\n token: string,\n agentEndpoint: string,\n backendGraphqlUrl: string | null = null,\n): RemoteConnectorExec {\n const agent = agentEndpoint.trim().replace(/\\/+$/, '');\n return (connector, action, params, options) =>\n execAction(agent, backendGraphqlUrl, token, connector, action, params, options);\n}\n\n/** file:// -> store URL via the agent's upload endpoint. */\nexport function createRemoteUploadMedia(token: string, indexUrl: string): (localUri: string) => Promise<string> {\n const agent = deriveAgentEndpoint(indexUrl);\n return async (localUri: string) => {\n const blob = await (await fetch(localUri)).blob();\n const filename = uploadFilenameFor(localUri);\n const resp = await fetch(`${agent}/v1/files/upload?filename=${encodeURIComponent(filename)}`, {\n method: 'POST',\n headers: { 'content-type': blob.type || 'application/octet-stream', authorization: `Bearer ${token}` },\n body: blob,\n });\n if (!resp.ok) throw new Error(`Upload failed (HTTP ${resp.status}): ${(await resp.text()).slice(0, 160)}`);\n const result = (await resp.json()) as { url?: string };\n if (!result.url) throw new Error('Upload returned no URL');\n return result.url;\n };\n}\n\n/**\n * Twin of web canvas `unwrapProxyUrl`: the connector fetches the reference\n * server-side, so pass the inner Google/store URL, not the agent proxy wrap.\n */\nexport function unwrapProxyUrl(src: string): string {\n try {\n const u = new URL(src);\n if (u.pathname.includes('/v1/files/proxy')) {\n const inner = u.searchParams.get('url');\n if (inner) return inner;\n }\n } catch {\n /* not a URL */\n }\n return src;\n}\n\n/** Google Veo URIs are not fetchable on device — route them through the agent proxy. */\nexport function proxiedMediaUrl(indexUrl: string, uri: string): string {\n if (!uri || uri.includes('/v1/files/proxy')) return uri;\n if (!/generativelanguage\\.googleapis|googleusercontent\\.com/i.test(uri)) return uri;\n return `${deriveAgentEndpoint(indexUrl)}/v1/files/proxy?url=${encodeURIComponent(uri)}`;\n}\n"],"names":[],"mappings":"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"}
|