mulmocast 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/templates/characters.json +16 -0
- package/assets/templates/html.json +6 -0
- package/lib/actions/audio.js +13 -19
- package/lib/actions/image_agents.d.ts +145 -0
- package/lib/actions/image_agents.js +59 -0
- package/lib/actions/image_references.d.ts +9 -0
- package/lib/actions/image_references.js +79 -0
- package/lib/actions/images.d.ts +17 -109
- package/lib/actions/images.js +83 -188
- package/lib/actions/index.d.ts +2 -0
- package/lib/actions/index.js +2 -0
- package/lib/actions/movie.js +3 -1
- package/lib/actions/pdf.js +5 -2
- package/lib/agents/image_google_agent.d.ts +2 -15
- package/lib/agents/image_google_agent.js +5 -5
- package/lib/agents/image_openai_agent.d.ts +2 -17
- package/lib/agents/image_openai_agent.js +9 -9
- package/lib/agents/movie_google_agent.d.ts +2 -17
- package/lib/agents/movie_google_agent.js +7 -7
- package/lib/agents/movie_replicate_agent.d.ts +2 -16
- package/lib/agents/movie_replicate_agent.js +4 -4
- package/lib/agents/tts_google_agent.d.ts +9 -1
- package/lib/agents/tts_google_agent.js +2 -2
- package/lib/agents/tts_nijivoice_agent.js +1 -1
- package/lib/agents/tts_openai_agent.d.ts +13 -1
- package/lib/agents/tts_openai_agent.js +2 -2
- package/lib/cli/helpers.js +7 -7
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/methods/index.d.ts +1 -0
- package/lib/methods/index.js +1 -0
- package/lib/methods/mulmo_beat.d.ts +6 -0
- package/lib/methods/mulmo_beat.js +21 -0
- package/lib/methods/mulmo_presentation_style.d.ts +3 -1
- package/lib/methods/mulmo_presentation_style.js +31 -7
- package/lib/methods/mulmo_studio_context.js +3 -0
- package/lib/tools/story_to_script.js +2 -2
- package/lib/types/agent.d.ts +55 -0
- package/lib/types/agent.js +3 -0
- package/lib/types/schema.d.ts +560 -296
- package/lib/types/schema.js +19 -10
- package/lib/types/type.d.ts +3 -2
- package/lib/utils/const.d.ts +0 -1
- package/lib/utils/const.js +0 -1
- package/lib/utils/context.d.ts +24 -13
- package/lib/utils/context.js +1 -0
- package/lib/utils/ffmpeg_utils.d.ts +1 -1
- package/lib/utils/ffmpeg_utils.js +1 -1
- package/lib/utils/file.js +4 -4
- package/lib/utils/filters.js +3 -4
- package/lib/utils/markdown.js +1 -1
- package/lib/utils/preprocess.d.ts +15 -8
- package/lib/utils/provider2agent.d.ts +72 -0
- package/lib/utils/provider2agent.js +81 -0
- package/lib/utils/string.js +5 -5
- package/lib/utils/utils.d.ts +13 -11
- package/lib/utils/utils.js +56 -62
- package/package.json +7 -6
- package/scripts/templates/html.json +42 -0
- package/scripts/templates/image_refs.json +35 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Story with multiple characters",
|
|
3
|
+
"description": "Template for story with multiple characters.",
|
|
4
|
+
"presentationStyle": {
|
|
5
|
+
"$mulmocast": {
|
|
6
|
+
"version": "1.0",
|
|
7
|
+
"credit": "closing"
|
|
8
|
+
},
|
|
9
|
+
"canvasSize": {
|
|
10
|
+
"width": 1536,
|
|
11
|
+
"height": 1024
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"systemPrompt": "Generate a script for a the given story with multiple characters. Generate image prompts for each character, and make references to them in the beats. Use the JSON below as a template.",
|
|
15
|
+
"scriptName": "image_refs.json"
|
|
16
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Business presentation in HTML",
|
|
3
|
+
"description": "Template for business presentation in HTML.",
|
|
4
|
+
"systemPrompt": "Generate a script for a business presentation of the given topic. Another LLM will generate actual slides from the prompt and data for each beat. Adding optional data would help it to generate more compelling slide. Mention the reference in one of beats, if it exists. The valid type of reference is 'article', 'paper', 'image', 'video', 'audio'. Use the JSON below as a template.",
|
|
5
|
+
"scriptName": "html.json"
|
|
6
|
+
}
|
package/lib/actions/audio.js
CHANGED
|
@@ -12,18 +12,10 @@ import { MulmoPresentationStyleMethods } from "../methods/index.js";
|
|
|
12
12
|
import { fileCacheAgentFilter } from "../utils/filters.js";
|
|
13
13
|
import { getAudioArtifactFilePath, getAudioFilePath, getOutputStudioFilePath, resolveDirPath, defaultBGMPath, mkdir, writingMessage } from "../utils/file.js";
|
|
14
14
|
import { text2hash, localizedText, settings2GraphAIConfig } from "../utils/utils.js";
|
|
15
|
+
import { provider2TTSAgent } from "../utils/provider2agent.js";
|
|
15
16
|
import { MulmoStudioContextMethods } from "../methods/mulmo_studio_context.js";
|
|
16
17
|
import { MulmoMediaSourceMethods } from "../methods/mulmo_media_source.js";
|
|
17
18
|
const vanillaAgents = agents.default ?? agents;
|
|
18
|
-
// const rion_takanashi_voice = "b9277ce3-ba1c-4f6f-9a65-c05ca102ded0"; // たかなし りおん
|
|
19
|
-
// const ben_carter_voice = "bc06c63f-fef6-43b6-92f7-67f919bd5dae"; // ベン・カーター
|
|
20
|
-
const provider_to_agent = {
|
|
21
|
-
nijivoice: "ttsNijivoiceAgent",
|
|
22
|
-
openai: "ttsOpenaiAgent",
|
|
23
|
-
google: "ttsGoogleAgent",
|
|
24
|
-
elevenlabs: "ttsElevenlabsAgent",
|
|
25
|
-
mock: "mediaMockAgent",
|
|
26
|
-
};
|
|
27
19
|
const getAudioPath = (context, beat, audioFile) => {
|
|
28
20
|
if (beat.audio?.type === "audio") {
|
|
29
21
|
const path = MulmoMediaSourceMethods.resolve(beat.audio.source, context);
|
|
@@ -40,7 +32,7 @@ const getAudioPath = (context, beat, audioFile) => {
|
|
|
40
32
|
const getAudioParam = (presentationStyle, beat) => {
|
|
41
33
|
const voiceId = MulmoPresentationStyleMethods.getVoiceId(presentationStyle, beat);
|
|
42
34
|
// Use speaker-specific provider if available, otherwise fall back to script-level provider
|
|
43
|
-
const provider = MulmoPresentationStyleMethods.
|
|
35
|
+
const provider = MulmoPresentationStyleMethods.getTTSProvider(presentationStyle, beat);
|
|
44
36
|
const speechOptions = MulmoPresentationStyleMethods.getSpeechOptions(presentationStyle, beat);
|
|
45
37
|
return { voiceId, provider, speechOptions };
|
|
46
38
|
};
|
|
@@ -61,7 +53,7 @@ const preprocessor = (namedInputs) => {
|
|
|
61
53
|
studioBeat.audioFile = audioPath; // TODO
|
|
62
54
|
const needsTTS = !beat.audio && audioPath !== undefined;
|
|
63
55
|
return {
|
|
64
|
-
ttsAgent:
|
|
56
|
+
ttsAgent: provider2TTSAgent[provider].agentName,
|
|
65
57
|
text,
|
|
66
58
|
voiceId,
|
|
67
59
|
speechOptions,
|
|
@@ -91,11 +83,13 @@ const graph_tts = {
|
|
|
91
83
|
agent: ":preprocessor.ttsAgent",
|
|
92
84
|
inputs: {
|
|
93
85
|
text: ":preprocessor.text",
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
86
|
+
cache: {
|
|
87
|
+
force: [":context.force"],
|
|
88
|
+
file: ":preprocessor.audioPath",
|
|
89
|
+
index: ":__mapIndex",
|
|
90
|
+
mulmoContext: ":context",
|
|
91
|
+
sessionType: "audio",
|
|
92
|
+
},
|
|
99
93
|
params: {
|
|
100
94
|
voice: ":preprocessor.voiceId",
|
|
101
95
|
speed: ":preprocessor.speechOptions.speed",
|
|
@@ -184,8 +178,8 @@ export const audioFilePath = (context) => {
|
|
|
184
178
|
const getConcurrency = (context) => {
|
|
185
179
|
// Check if any speaker uses nijivoice or elevenlabs (providers that require concurrency = 1)
|
|
186
180
|
const hasLimitedConcurrencyProvider = Object.values(context.presentationStyle.speechParams.speakers).some((speaker) => {
|
|
187
|
-
const provider = speaker.provider ?? context.presentationStyle.speechParams.provider;
|
|
188
|
-
return provider
|
|
181
|
+
const provider = (speaker.provider ?? context.presentationStyle.speechParams.provider);
|
|
182
|
+
return provider2TTSAgent[provider].hasLimitedConcurrency;
|
|
189
183
|
});
|
|
190
184
|
return hasLimitedConcurrencyProvider ? 1 : 8;
|
|
191
185
|
};
|
|
@@ -239,7 +233,7 @@ export const audio = async (context, settings, callbacks) => {
|
|
|
239
233
|
const outputStudioFilePath = getOutputStudioFilePath(outDirPath, fileName);
|
|
240
234
|
mkdir(outDirPath);
|
|
241
235
|
mkdir(audioSegmentDirPath);
|
|
242
|
-
const config = settings2GraphAIConfig(settings);
|
|
236
|
+
const config = settings2GraphAIConfig(settings, process.env);
|
|
243
237
|
const taskManager = new TaskManager(getConcurrency(context));
|
|
244
238
|
const graph = new GraphAI(graph_data, audioAgents, { agentFilters, taskManager, config });
|
|
245
239
|
graph.injectValue("context", context);
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { MulmoStudioContext, MulmoBeat, MulmoCanvasDimension } from "../types/index.js";
|
|
2
|
+
export declare const imagePreprocessAgent: (namedInputs: {
|
|
3
|
+
context: MulmoStudioContext;
|
|
4
|
+
beat: MulmoBeat;
|
|
5
|
+
index: number;
|
|
6
|
+
imageRefs: Record<string, string>;
|
|
7
|
+
}) => Promise<{
|
|
8
|
+
imagePath: string;
|
|
9
|
+
htmlPrompt: string | undefined;
|
|
10
|
+
htmlPath: string;
|
|
11
|
+
htmlImageSystemPrompt: string[];
|
|
12
|
+
} | {
|
|
13
|
+
imagePath: string | undefined;
|
|
14
|
+
referenceImageForMovie: string | undefined;
|
|
15
|
+
imageParams: {
|
|
16
|
+
provider: string;
|
|
17
|
+
style?: string | undefined;
|
|
18
|
+
model?: string | undefined;
|
|
19
|
+
moderation?: string | undefined;
|
|
20
|
+
images?: Record<string, {
|
|
21
|
+
type: "image";
|
|
22
|
+
source: {
|
|
23
|
+
url: string;
|
|
24
|
+
kind: "url";
|
|
25
|
+
} | {
|
|
26
|
+
kind: "base64";
|
|
27
|
+
data: string;
|
|
28
|
+
} | {
|
|
29
|
+
text: string;
|
|
30
|
+
kind: "text";
|
|
31
|
+
} | {
|
|
32
|
+
path: string;
|
|
33
|
+
kind: "path";
|
|
34
|
+
};
|
|
35
|
+
} | {
|
|
36
|
+
type: "imagePrompt";
|
|
37
|
+
prompt: string;
|
|
38
|
+
}> | undefined;
|
|
39
|
+
};
|
|
40
|
+
movieFile: string | undefined;
|
|
41
|
+
htmlPrompt?: undefined;
|
|
42
|
+
htmlPath?: undefined;
|
|
43
|
+
htmlImageSystemPrompt?: undefined;
|
|
44
|
+
} | {
|
|
45
|
+
imagePath: string;
|
|
46
|
+
imageFromMovie: boolean;
|
|
47
|
+
movieParams: {
|
|
48
|
+
speed?: number | undefined;
|
|
49
|
+
model?: string | undefined;
|
|
50
|
+
fillOption?: {
|
|
51
|
+
style: "aspectFit" | "aspectFill";
|
|
52
|
+
} | undefined;
|
|
53
|
+
provider?: string | undefined;
|
|
54
|
+
transition?: {
|
|
55
|
+
type: "fade" | "slideout_left";
|
|
56
|
+
duration: number;
|
|
57
|
+
} | undefined;
|
|
58
|
+
};
|
|
59
|
+
imageParams: {
|
|
60
|
+
provider: string;
|
|
61
|
+
style?: string | undefined;
|
|
62
|
+
model?: string | undefined;
|
|
63
|
+
moderation?: string | undefined;
|
|
64
|
+
images?: Record<string, {
|
|
65
|
+
type: "image";
|
|
66
|
+
source: {
|
|
67
|
+
url: string;
|
|
68
|
+
kind: "url";
|
|
69
|
+
} | {
|
|
70
|
+
kind: "base64";
|
|
71
|
+
data: string;
|
|
72
|
+
} | {
|
|
73
|
+
text: string;
|
|
74
|
+
kind: "text";
|
|
75
|
+
} | {
|
|
76
|
+
path: string;
|
|
77
|
+
kind: "path";
|
|
78
|
+
};
|
|
79
|
+
} | {
|
|
80
|
+
type: "imagePrompt";
|
|
81
|
+
prompt: string;
|
|
82
|
+
}> | undefined;
|
|
83
|
+
};
|
|
84
|
+
movieFile: string | undefined;
|
|
85
|
+
htmlPrompt?: undefined;
|
|
86
|
+
htmlPath?: undefined;
|
|
87
|
+
htmlImageSystemPrompt?: undefined;
|
|
88
|
+
} | {
|
|
89
|
+
imagePath: string;
|
|
90
|
+
referenceImageForMovie: string;
|
|
91
|
+
imageAgentInfo: import("../types/type.js").Text2ImageAgentInfo;
|
|
92
|
+
prompt: string;
|
|
93
|
+
referenceImages: string[];
|
|
94
|
+
movieParams: {
|
|
95
|
+
speed?: number | undefined;
|
|
96
|
+
model?: string | undefined;
|
|
97
|
+
fillOption?: {
|
|
98
|
+
style: "aspectFit" | "aspectFill";
|
|
99
|
+
} | undefined;
|
|
100
|
+
provider?: string | undefined;
|
|
101
|
+
transition?: {
|
|
102
|
+
type: "fade" | "slideout_left";
|
|
103
|
+
duration: number;
|
|
104
|
+
} | undefined;
|
|
105
|
+
};
|
|
106
|
+
imageParams: {
|
|
107
|
+
provider: string;
|
|
108
|
+
style?: string | undefined;
|
|
109
|
+
model?: string | undefined;
|
|
110
|
+
moderation?: string | undefined;
|
|
111
|
+
images?: Record<string, {
|
|
112
|
+
type: "image";
|
|
113
|
+
source: {
|
|
114
|
+
url: string;
|
|
115
|
+
kind: "url";
|
|
116
|
+
} | {
|
|
117
|
+
kind: "base64";
|
|
118
|
+
data: string;
|
|
119
|
+
} | {
|
|
120
|
+
text: string;
|
|
121
|
+
kind: "text";
|
|
122
|
+
} | {
|
|
123
|
+
path: string;
|
|
124
|
+
kind: "path";
|
|
125
|
+
};
|
|
126
|
+
} | {
|
|
127
|
+
type: "imagePrompt";
|
|
128
|
+
prompt: string;
|
|
129
|
+
}> | undefined;
|
|
130
|
+
};
|
|
131
|
+
movieFile: string | undefined;
|
|
132
|
+
htmlPrompt?: undefined;
|
|
133
|
+
htmlPath?: undefined;
|
|
134
|
+
htmlImageSystemPrompt?: undefined;
|
|
135
|
+
}>;
|
|
136
|
+
export declare const imagePluginAgent: (namedInputs: {
|
|
137
|
+
context: MulmoStudioContext;
|
|
138
|
+
beat: MulmoBeat;
|
|
139
|
+
index: number;
|
|
140
|
+
}) => Promise<void>;
|
|
141
|
+
export declare const htmlImageGeneratorAgent: (namedInputs: {
|
|
142
|
+
file: string;
|
|
143
|
+
canvasSize: MulmoCanvasDimension;
|
|
144
|
+
htmlText: string;
|
|
145
|
+
}) => Promise<void>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { MulmoPresentationStyleMethods, MulmoStudioContextMethods, MulmoBeatMethods } from "../methods/index.js";
|
|
2
|
+
import { getBeatPngImagePath, getBeatMoviePath } from "../utils/file.js";
|
|
3
|
+
import { imagePrompt, htmlImageSystemPrompt } from "../utils/prompt.js";
|
|
4
|
+
import { renderHTMLToImage } from "../utils/markdown.js";
|
|
5
|
+
import { GraphAILogger } from "graphai";
|
|
6
|
+
const htmlStyle = (context, beat) => {
|
|
7
|
+
return {
|
|
8
|
+
canvasSize: MulmoPresentationStyleMethods.getCanvasSize(context.presentationStyle),
|
|
9
|
+
textSlideStyle: MulmoPresentationStyleMethods.getTextSlideStyle(context.presentationStyle, beat),
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export const imagePreprocessAgent = async (namedInputs) => {
|
|
13
|
+
const { context, beat, index, imageRefs } = namedInputs;
|
|
14
|
+
const imagePath = getBeatPngImagePath(context, index);
|
|
15
|
+
if (beat.htmlPrompt) {
|
|
16
|
+
const htmlPrompt = MulmoBeatMethods.getHtmlPrompt(beat);
|
|
17
|
+
const htmlPath = imagePath.replace(/\.[^/.]+$/, ".html");
|
|
18
|
+
return { imagePath, htmlPrompt, htmlPath, htmlImageSystemPrompt: htmlImageSystemPrompt(context.presentationStyle.canvasSize) };
|
|
19
|
+
}
|
|
20
|
+
const imageAgentInfo = MulmoPresentationStyleMethods.getImageAgentInfo(context.presentationStyle, beat);
|
|
21
|
+
const returnValue = {
|
|
22
|
+
imageParams: imageAgentInfo.imageParams,
|
|
23
|
+
movieFile: beat.moviePrompt ? getBeatMoviePath(context, index) : undefined,
|
|
24
|
+
};
|
|
25
|
+
if (beat.image) {
|
|
26
|
+
const plugin = MulmoBeatMethods.getPlugin(beat);
|
|
27
|
+
const pluginPath = plugin.path({ beat, context, imagePath, ...htmlStyle(context, beat) });
|
|
28
|
+
// undefined prompt indicates that image generation is not needed
|
|
29
|
+
return { ...returnValue, imagePath: pluginPath, referenceImageForMovie: pluginPath };
|
|
30
|
+
}
|
|
31
|
+
const movieParams = { ...context.presentationStyle.movieParams, ...beat.movieParams };
|
|
32
|
+
GraphAILogger.log(`movieParams: ${index}`, movieParams, beat.moviePrompt);
|
|
33
|
+
if (beat.moviePrompt && !beat.imagePrompt) {
|
|
34
|
+
return { ...returnValue, imagePath, imageFromMovie: true, movieParams }; // no image prompt, only movie prompt
|
|
35
|
+
}
|
|
36
|
+
// referenceImages for "edit_image", openai agent.
|
|
37
|
+
const referenceImages = MulmoBeatMethods.getImageReferenceForImageGenerator(beat, imageRefs);
|
|
38
|
+
const prompt = imagePrompt(beat, imageAgentInfo.imageParams.style);
|
|
39
|
+
return { ...returnValue, imagePath, referenceImageForMovie: imagePath, imageAgentInfo, prompt, referenceImages, movieParams };
|
|
40
|
+
};
|
|
41
|
+
export const imagePluginAgent = async (namedInputs) => {
|
|
42
|
+
const { context, beat, index } = namedInputs;
|
|
43
|
+
const imagePath = getBeatPngImagePath(context, index);
|
|
44
|
+
const plugin = MulmoBeatMethods.getPlugin(beat);
|
|
45
|
+
try {
|
|
46
|
+
MulmoStudioContextMethods.setBeatSessionState(context, "image", index, true);
|
|
47
|
+
const processorParams = { beat, context, imagePath, ...htmlStyle(context, beat) };
|
|
48
|
+
await plugin.process(processorParams);
|
|
49
|
+
MulmoStudioContextMethods.setBeatSessionState(context, "image", index, false);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
MulmoStudioContextMethods.setBeatSessionState(context, "image", index, false);
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
export const htmlImageGeneratorAgent = async (namedInputs) => {
|
|
57
|
+
const { file, canvasSize, htmlText } = namedInputs;
|
|
58
|
+
await renderHTMLToImage(htmlText, file, canvasSize.width, canvasSize.height);
|
|
59
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { MulmoStudioContext, MulmoImagePromptMedia } from "../types/index.js";
|
|
2
|
+
export declare const generateReferenceImage: (inputs: {
|
|
3
|
+
context: MulmoStudioContext;
|
|
4
|
+
key: string;
|
|
5
|
+
index: number;
|
|
6
|
+
image: MulmoImagePromptMedia;
|
|
7
|
+
force?: boolean;
|
|
8
|
+
}) => Promise<string>;
|
|
9
|
+
export declare const getImageRefs: (context: MulmoStudioContext) => Promise<Record<string, string>>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import { GraphAI } from "graphai";
|
|
3
|
+
import { getReferenceImagePath } from "../utils/file.js";
|
|
4
|
+
import { getExtention } from "../utils/utils.js";
|
|
5
|
+
import { graphOption } from "./images.js";
|
|
6
|
+
import { MulmoPresentationStyleMethods, MulmoStudioContextMethods } from "../methods/index.js";
|
|
7
|
+
import { imageGoogleAgent, imageOpenaiAgent } from "../agents/index.js";
|
|
8
|
+
// public api
|
|
9
|
+
// Application may call this function directly to generate reference image.
|
|
10
|
+
export const generateReferenceImage = async (inputs) => {
|
|
11
|
+
const { context, key, index, image, force } = inputs;
|
|
12
|
+
const imagePath = getReferenceImagePath(context, key, "png");
|
|
13
|
+
// generate image
|
|
14
|
+
const imageAgentInfo = MulmoPresentationStyleMethods.getImageAgentInfo(context.presentationStyle);
|
|
15
|
+
const prompt = `${image.prompt}\n${imageAgentInfo.imageParams.style || ""}`;
|
|
16
|
+
const image_graph_data = {
|
|
17
|
+
version: 0.5,
|
|
18
|
+
nodes: {
|
|
19
|
+
imageGenerator: {
|
|
20
|
+
agent: imageAgentInfo.agent,
|
|
21
|
+
retry: 2,
|
|
22
|
+
inputs: {
|
|
23
|
+
prompt,
|
|
24
|
+
cache: {
|
|
25
|
+
force: [context.force, force ?? false],
|
|
26
|
+
file: imagePath,
|
|
27
|
+
index,
|
|
28
|
+
mulmoContext: context,
|
|
29
|
+
sessionType: "imageReference",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
params: {
|
|
33
|
+
model: imageAgentInfo.imageParams.model,
|
|
34
|
+
canvasSize: context.presentationStyle.canvasSize,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
const options = await graphOption(context);
|
|
40
|
+
const graph = new GraphAI(image_graph_data, { imageGoogleAgent, imageOpenaiAgent }, options);
|
|
41
|
+
await graph.run();
|
|
42
|
+
return imagePath;
|
|
43
|
+
};
|
|
44
|
+
const downLoadImage = async (context, key, url) => {
|
|
45
|
+
const response = await fetch(url);
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
throw new Error(`Failed to download image: ${url}`);
|
|
48
|
+
}
|
|
49
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
50
|
+
// Detect file extension from Content-Type header or URL
|
|
51
|
+
const extension = getExtention(response.headers.get("content-type"), url);
|
|
52
|
+
const imagePath = getReferenceImagePath(context, key, extension);
|
|
53
|
+
await fs.promises.writeFile(imagePath, buffer);
|
|
54
|
+
return imagePath;
|
|
55
|
+
};
|
|
56
|
+
export const getImageRefs = async (context) => {
|
|
57
|
+
const images = context.presentationStyle.imageParams?.images;
|
|
58
|
+
if (!images) {
|
|
59
|
+
return {};
|
|
60
|
+
}
|
|
61
|
+
const imageRefs = {};
|
|
62
|
+
await Promise.all(Object.keys(images)
|
|
63
|
+
.sort()
|
|
64
|
+
.map(async (key, index) => {
|
|
65
|
+
const image = images[key];
|
|
66
|
+
if (image.type === "imagePrompt") {
|
|
67
|
+
imageRefs[key] = await generateReferenceImage({ context, key, index, image, force: false });
|
|
68
|
+
}
|
|
69
|
+
else if (image.type === "image") {
|
|
70
|
+
if (image.source.kind === "path") {
|
|
71
|
+
imageRefs[key] = MulmoStudioContextMethods.resolveAssetPath(context, image.source.path);
|
|
72
|
+
}
|
|
73
|
+
else if (image.source.kind === "url") {
|
|
74
|
+
imageRefs[key] = await downLoadImage(context, key, image.source.url);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}));
|
|
78
|
+
return imageRefs;
|
|
79
|
+
};
|
package/lib/actions/images.d.ts
CHANGED
|
@@ -1,112 +1,20 @@
|
|
|
1
|
-
import type { CallbackFunction } from "graphai";
|
|
2
|
-
import { MulmoStudioContext
|
|
3
|
-
export declare const
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import type { GraphOptions, CallbackFunction } from "graphai";
|
|
2
|
+
import { MulmoStudioContext } from "../types/index.js";
|
|
3
|
+
export declare const graphOption: (context: MulmoStudioContext, settings?: Record<string, string>) => Promise<GraphOptions>;
|
|
4
|
+
type ImageOptions = {
|
|
5
|
+
imageAgents: Record<string, unknown>;
|
|
6
|
+
};
|
|
7
|
+
export declare const images: (context: MulmoStudioContext, args?: {
|
|
8
|
+
settings?: Record<string, string>;
|
|
9
|
+
callbacks?: CallbackFunction[];
|
|
10
|
+
options?: ImageOptions;
|
|
11
|
+
}) => Promise<MulmoStudioContext>;
|
|
12
|
+
export declare const generateBeatImage: (inputs: {
|
|
6
13
|
index: number;
|
|
7
|
-
imageRefs: Record<string, string>;
|
|
8
|
-
}) => Promise<{
|
|
9
|
-
imageParams: {
|
|
10
|
-
provider: "openai" | "google";
|
|
11
|
-
style?: string | undefined;
|
|
12
|
-
model?: string | undefined;
|
|
13
|
-
moderation?: string | undefined;
|
|
14
|
-
images?: Record<string, {
|
|
15
|
-
type: "image";
|
|
16
|
-
source: {
|
|
17
|
-
url: string;
|
|
18
|
-
kind: "url";
|
|
19
|
-
} | {
|
|
20
|
-
kind: "base64";
|
|
21
|
-
data: string;
|
|
22
|
-
} | {
|
|
23
|
-
text: string;
|
|
24
|
-
kind: "text";
|
|
25
|
-
} | {
|
|
26
|
-
path: string;
|
|
27
|
-
kind: "path";
|
|
28
|
-
};
|
|
29
|
-
}> | undefined;
|
|
30
|
-
};
|
|
31
|
-
movieFile: string | undefined;
|
|
32
|
-
imagePath: string | undefined;
|
|
33
|
-
referenceImage: string | undefined;
|
|
34
|
-
htmlPrompt?: undefined;
|
|
35
|
-
htmlPath?: undefined;
|
|
36
|
-
htmlImageSystemPrompt?: undefined;
|
|
37
|
-
} | {
|
|
38
|
-
imagePath: string;
|
|
39
|
-
htmlPrompt: string;
|
|
40
|
-
htmlPath: string;
|
|
41
|
-
htmlImageSystemPrompt: string[];
|
|
42
|
-
} | {
|
|
43
|
-
imagePath: string;
|
|
44
|
-
images: string[];
|
|
45
|
-
imageFromMovie: boolean;
|
|
46
|
-
imageParams: {
|
|
47
|
-
provider: "openai" | "google";
|
|
48
|
-
style?: string | undefined;
|
|
49
|
-
model?: string | undefined;
|
|
50
|
-
moderation?: string | undefined;
|
|
51
|
-
images?: Record<string, {
|
|
52
|
-
type: "image";
|
|
53
|
-
source: {
|
|
54
|
-
url: string;
|
|
55
|
-
kind: "url";
|
|
56
|
-
} | {
|
|
57
|
-
kind: "base64";
|
|
58
|
-
data: string;
|
|
59
|
-
} | {
|
|
60
|
-
text: string;
|
|
61
|
-
kind: "text";
|
|
62
|
-
} | {
|
|
63
|
-
path: string;
|
|
64
|
-
kind: "path";
|
|
65
|
-
};
|
|
66
|
-
}> | undefined;
|
|
67
|
-
};
|
|
68
|
-
movieFile: string | undefined;
|
|
69
|
-
htmlPrompt?: undefined;
|
|
70
|
-
htmlPath?: undefined;
|
|
71
|
-
htmlImageSystemPrompt?: undefined;
|
|
72
|
-
} | {
|
|
73
|
-
images: string[];
|
|
74
|
-
imageParams: {
|
|
75
|
-
provider: "openai" | "google";
|
|
76
|
-
style?: string | undefined;
|
|
77
|
-
model?: string | undefined;
|
|
78
|
-
moderation?: string | undefined;
|
|
79
|
-
images?: Record<string, {
|
|
80
|
-
type: "image";
|
|
81
|
-
source: {
|
|
82
|
-
url: string;
|
|
83
|
-
kind: "url";
|
|
84
|
-
} | {
|
|
85
|
-
kind: "base64";
|
|
86
|
-
data: string;
|
|
87
|
-
} | {
|
|
88
|
-
text: string;
|
|
89
|
-
kind: "text";
|
|
90
|
-
} | {
|
|
91
|
-
path: string;
|
|
92
|
-
kind: "path";
|
|
93
|
-
};
|
|
94
|
-
}> | undefined;
|
|
95
|
-
};
|
|
96
|
-
movieFile: string | undefined;
|
|
97
|
-
imageAgentInfo: import("../types/type.js").Text2ImageAgentInfo;
|
|
98
|
-
imagePath: string;
|
|
99
|
-
referenceImage: string;
|
|
100
|
-
prompt: string;
|
|
101
|
-
htmlPrompt?: undefined;
|
|
102
|
-
htmlPath?: undefined;
|
|
103
|
-
htmlImageSystemPrompt?: undefined;
|
|
104
|
-
}>;
|
|
105
|
-
export declare const imagePluginAgent: (namedInputs: {
|
|
106
14
|
context: MulmoStudioContext;
|
|
107
|
-
|
|
108
|
-
|
|
15
|
+
settings?: Record<string, string>;
|
|
16
|
+
callbacks?: CallbackFunction[];
|
|
17
|
+
forceMovie?: boolean;
|
|
18
|
+
forceImage?: boolean;
|
|
109
19
|
}) => Promise<void>;
|
|
110
|
-
export
|
|
111
|
-
export declare const images: (context: MulmoStudioContext, settings?: Record<string, string>, callbacks?: CallbackFunction[]) => Promise<MulmoStudioContext>;
|
|
112
|
-
export declare const generateBeatImage: (index: number, context: MulmoStudioContext, settings?: Record<string, string>, callbacks?: CallbackFunction[]) => Promise<void>;
|
|
20
|
+
export {};
|