mulmocast 0.1.6 → 1.1.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.
Files changed (58) hide show
  1. package/assets/templates/akira_comic.json +1 -1
  2. package/assets/templates/ani.json +48 -0
  3. package/assets/templates/ani_ja.json +44 -0
  4. package/assets/templates/characters.json +1 -1
  5. package/assets/templates/children_book.json +1 -1
  6. package/assets/templates/comic_strips.json +1 -1
  7. package/assets/templates/drslump_comic.json +1 -1
  8. package/assets/templates/ghibli_comic.json +1 -1
  9. package/assets/templates/ghibli_image_only.json +1 -1
  10. package/assets/templates/ghibli_shorts.json +2 -3
  11. package/assets/templates/ghost_comic.json +1 -1
  12. package/assets/templates/onepiece_comic.json +1 -1
  13. package/assets/templates/portrait_movie.json +1 -1
  14. package/assets/templates/realistic_movie.json +1 -1
  15. package/assets/templates/sensei_and_taro.json +4 -5
  16. package/assets/templates/shorts.json +1 -1
  17. package/assets/templates/trailer.json +1 -1
  18. package/lib/actions/audio.js +8 -7
  19. package/lib/actions/image_agents.d.ts +53 -98
  20. package/lib/actions/image_agents.js +14 -6
  21. package/lib/actions/images.js +42 -13
  22. package/lib/actions/movie.js +1 -1
  23. package/lib/agents/index.d.ts +2 -1
  24. package/lib/agents/index.js +2 -1
  25. package/lib/agents/movie_replicate_agent.js +18 -5
  26. package/lib/agents/sound_effect_replicate_agent.d.ts +5 -0
  27. package/lib/agents/sound_effect_replicate_agent.js +59 -0
  28. package/lib/cli/commands/tool/scripting/builder.js +1 -1
  29. package/lib/cli/commands/tool/scripting/handler.d.ts +1 -1
  30. package/lib/cli/commands/tool/story_to_script/builder.js +1 -1
  31. package/lib/cli/commands/tool/story_to_script/handler.d.ts +1 -1
  32. package/lib/mcp/server.js +2 -2
  33. package/lib/methods/index.d.ts +1 -0
  34. package/lib/methods/index.js +1 -0
  35. package/lib/methods/mulmo_presentation_style.d.ts +25 -6
  36. package/lib/methods/mulmo_presentation_style.js +33 -30
  37. package/lib/methods/mulmo_script.d.ts +4 -0
  38. package/lib/methods/mulmo_script.js +31 -0
  39. package/lib/tools/story_to_script.d.ts +1 -1
  40. package/lib/types/agent.d.ts +9 -0
  41. package/lib/types/schema.d.ts +727 -554
  42. package/lib/types/schema.js +41 -24
  43. package/lib/types/type.d.ts +4 -4
  44. package/lib/utils/assets.d.ts +18 -0
  45. package/lib/utils/assets.js +101 -0
  46. package/lib/utils/context.d.ts +98 -84
  47. package/lib/utils/context.js +2 -1
  48. package/lib/utils/ffmpeg_utils.js +6 -0
  49. package/lib/utils/file.d.ts +4 -1
  50. package/lib/utils/file.js +3 -5
  51. package/lib/utils/preprocess.d.ts +57 -47
  52. package/lib/utils/preprocess.js +7 -5
  53. package/lib/utils/provider2agent.d.ts +27 -7
  54. package/lib/utils/provider2agent.js +85 -7
  55. package/lib/utils/utils.d.ts +1 -2
  56. package/lib/utils/utils.js +4 -2
  57. package/package.json +7 -7
  58. package/scripts/templates/presentation.json~ +0 -119
@@ -4,7 +4,7 @@
4
4
  "systemPrompt": "Generate a script for a presentation of the given topic. Another AI will generate images for each beat based on the image prompt of that beat. Mention the reference in one of beats, if it exists. Use the JSON below as a template.",
5
5
  "presentationStyle": {
6
6
  "$mulmocast": {
7
- "version": "1.0",
7
+ "version": "1.1",
8
8
  "credit": "closing"
9
9
  },
10
10
  "canvasSize": {
@@ -0,0 +1,48 @@
1
+ {
2
+ "title": "Presentation with Ani in Japanese",
3
+ "description": "Template for presentation with Ani in Japanese.",
4
+ "systemPrompt": "Generate a script for a presentation of the given topic. 言葉づかいは少しツンデレにして。Another AI will generate comic for each beat based on the image prompt of that beat. You don't need to specify the style of the image, just describe the scene. Mention the reference in one of beats, if it exists. Use the JSON below as a template. Create appropriate amount of beats, and make sure the beats are coherent and flow well.",
5
+ "presentationStyle": {
6
+ "$mulmocast": {
7
+ "version": "1.1",
8
+ "credit": "closing"
9
+ },
10
+ "movieParams": {
11
+ "provider": "replicate",
12
+ "model": "bytedance/seedance-1-lite"
13
+ },
14
+ "speechParams": {
15
+ "provider": "openai",
16
+ "speakers": {
17
+ "Presenter": {
18
+ "voiceId": "shimmer",
19
+ "speechOptions": { "instruction": "Speak in a slightly high-pitched, curt tone with sudden flustered shifts—like a tsundere anime girl." }
20
+ }
21
+ }
22
+ },
23
+ "audioParams": {
24
+ "bgm": {
25
+ "kind": "url",
26
+ "url": "https://github.com/receptron/mulmocast-media/raw/refs/heads/main/bgms/morning001.mp3"
27
+ }
28
+ },
29
+ "lang": "en",
30
+ "canvasSize": {
31
+ "width": 1024,
32
+ "height": 1536
33
+ },
34
+ "imageParams": {
35
+ "style": "<style>A highly polished 2D digital illustration in anime and manga style, featuring clean linework, soft shading, vivid colors, and expressive facial detailing. The composition emphasizes clarity and visual impact with a minimalistic background and a strong character focus. The lighting is even and bright, giving the image a crisp and energetic feel, reminiscent of high-quality character art used in Japanese visual novels or mobile games.</style>",
36
+ "images": {
37
+ "ani": {
38
+ "type": "image",
39
+ "source": {
40
+ "kind": "url",
41
+ "url": "https://raw.githubusercontent.com/receptron/mulmocast-media/refs/heads/main/characters/ani.png"
42
+ }
43
+ }
44
+ }
45
+ }
46
+ },
47
+ "scriptName": "image_prompts_template.json"
48
+ }
@@ -0,0 +1,44 @@
1
+ {
2
+ "title": "Presentation with Ani",
3
+ "description": "Template for presentation with Ani.",
4
+ "systemPrompt": "Generate a Japanese script for a presentation of the given topic. 言葉づかいは少しツンデレにして。Another AI will generate comic for each beat based on the image prompt of that beat. You don't need to specify the style of the image, just describe the scene. Mention the reference in one of beats, if it exists. Use the JSON below as a template. Create appropriate amount of beats, and make sure the beats are coherent and flow well.",
5
+ "presentationStyle": {
6
+ "$mulmocast": {
7
+ "version": "1.1",
8
+ "credit": "closing"
9
+ },
10
+ "movieParams": {
11
+ "provider": "replicate",
12
+ "model": "bytedance/seedance-1-lite"
13
+ },
14
+ "audioParams": {
15
+ "bgm": {
16
+ "kind": "url",
17
+ "url": "https://github.com/receptron/mulmocast-media/raw/refs/heads/main/bgms/morning001.mp3"
18
+ }
19
+ },
20
+ "lang": "ja",
21
+ "canvasSize": {
22
+ "width": 1024,
23
+ "height": 1536
24
+ },
25
+ "speechParams": {
26
+ "speakers": {
27
+ "Presenter": { "provider": "nijivoice", "voiceId": "9d9ed276-49ee-443a-bc19-26e6136d05f0" }
28
+ }
29
+ },
30
+ "imageParams": {
31
+ "style": "<style>A highly polished 2D digital illustration in anime and manga style, featuring clean linework, soft shading, vivid colors, and expressive facial detailing. The composition emphasizes clarity and visual impact with a minimalistic background and a strong character focus. The lighting is even and bright, giving the image a crisp and energetic feel, reminiscent of high-quality character art used in Japanese visual novels or mobile games.</style>",
32
+ "images": {
33
+ "ani": {
34
+ "type": "image",
35
+ "source": {
36
+ "kind": "url",
37
+ "url": "https://raw.githubusercontent.com/receptron/mulmocast-media/refs/heads/main/characters/ani.png"
38
+ }
39
+ }
40
+ }
41
+ }
42
+ },
43
+ "scriptName": "image_prompts_template.json"
44
+ }
@@ -3,7 +3,7 @@
3
3
  "description": "Template for story with multiple characters.",
4
4
  "presentationStyle": {
5
5
  "$mulmocast": {
6
- "version": "1.0",
6
+ "version": "1.1",
7
7
  "credit": "closing"
8
8
  },
9
9
  "canvasSize": {
@@ -4,7 +4,7 @@
4
4
  "systemPrompt": "Please generate a script for a children book on the topic provided by the user. Each page (=beat) must haven an image prompt appropriate for the text.",
5
5
  "presentationStyle": {
6
6
  "$mulmocast": {
7
- "version": "1.0",
7
+ "version": "1.1",
8
8
  "credit": "closing"
9
9
  },
10
10
  "canvasSize": {
@@ -4,7 +4,7 @@
4
4
  "systemPrompt": "Generate a script for a presentation of the given topic. Another AI will generate comic strips for each beat based on the text description of that beat. Mention the reference in one of beats, if it exists. Use the JSON below as a template.",
5
5
  "presentationStyle": {
6
6
  "$mulmocast": {
7
- "version": "1.0",
7
+ "version": "1.1",
8
8
  "credit": "closing"
9
9
  },
10
10
  "canvasSize": {
@@ -4,7 +4,7 @@
4
4
  "systemPrompt": "Generate a script for a presentation of the given topic. Another AI will generate images for each beat based on the image prompt of that beat. Mention the reference in one of beats, if it exists. Use the JSON below as a template.",
5
5
  "presentationStyle": {
6
6
  "$mulmocast": {
7
- "version": "1.0",
7
+ "version": "1.1",
8
8
  "credit": "closing"
9
9
  },
10
10
  "canvasSize": {
@@ -4,7 +4,7 @@
4
4
  "systemPrompt": "Generate a script for a presentation of the given topic. Another AI will generate comic strips for each beat based on the text description of that beat. Mention the reference in one of beats, if it exists. Use the JSON below as a template.",
5
5
  "presentationStyle": {
6
6
  "$mulmocast": {
7
- "version": "1.0",
7
+ "version": "1.1",
8
8
  "credit": "closing"
9
9
  },
10
10
  "canvasSize": {
@@ -4,7 +4,7 @@
4
4
  "systemPrompt": "Generate a script for a presentation of the given topic. Another AI will generate an image for each beat based on the text description of that beat. Use the JSON below as a template.",
5
5
  "presentationStyle": {
6
6
  "$mulmocast": {
7
- "version": "1.0",
7
+ "version": "1.1",
8
8
  "credit": "closing"
9
9
  },
10
10
  "canvasSize": {
@@ -4,7 +4,7 @@
4
4
  "systemPrompt": "Generate a Japanese script for a Youtube shorts of the given topic. Another AI will generate comic strips for each beat based on the text description of that beat. Mention the reference in one of beats, if it exists. Use the JSON below as a template.",
5
5
  "presentationStyle": {
6
6
  "$mulmocast": {
7
- "version": "1.0",
7
+ "version": "1.1",
8
8
  "credit": "closing"
9
9
  },
10
10
  "canvasSize": {
@@ -12,9 +12,8 @@
12
12
  "height": 1536
13
13
  },
14
14
  "speechParams": {
15
- "provider": "nijivoice",
16
15
  "speakers": {
17
- "Presenter": { "voiceId": "3708ad43-cace-486c-a4ca-8fe41186e20c", "speechOptions": { "speed": 1.5 } }
16
+ "Presenter": { "provider": "nijivoice", "voiceId": "3708ad43-cace-486c-a4ca-8fe41186e20c", "speechOptions": { "speed": 1.5 } }
18
17
  }
19
18
  },
20
19
  "imageParams": {
@@ -4,7 +4,7 @@
4
4
  "systemPrompt": "Generate a script for a presentation of the given topic. Another AI will generate images for each beat based on the image prompt of that beat. Mention the reference in one of beats, if it exists. Use the JSON below as a template.",
5
5
  "presentationStyle": {
6
6
  "$mulmocast": {
7
- "version": "1.0",
7
+ "version": "1.1",
8
8
  "credit": "closing"
9
9
  },
10
10
  "canvasSize": {
@@ -4,7 +4,7 @@
4
4
  "systemPrompt": "Generate a script for a presentation of the given topic. Another AI will generate images for each beat based on the image prompt of that beat. Mention the reference in one of beats, if it exists. Use the JSON below as a template.",
5
5
  "presentationStyle": {
6
6
  "$mulmocast": {
7
- "version": "1.0",
7
+ "version": "1.1",
8
8
  "credit": "closing"
9
9
  },
10
10
  "canvasSize": {
@@ -4,7 +4,7 @@
4
4
  "systemPrompt": "Generate a script for a presentation of the given topic. Another AI will generate images for each beat based on the image prompt of that beat. Movie prompts must be written in English. Mention the reference in one of beats, if it exists. Use the JSON below as a template.",
5
5
  "presentationStyle": {
6
6
  "$mulmocast": {
7
- "version": "1.0",
7
+ "version": "1.1",
8
8
  "credit": "closing"
9
9
  },
10
10
  "canvasSize": {
@@ -4,7 +4,7 @@
4
4
  "systemPrompt": "Generate a script for a presentation of the given topic. Another AI will generate images for each beat based on the image prompt of that beat. Movie prompts must be written in English. Mention the reference in one of beats, if it exists. Use the JSON below as a template.",
5
5
  "presentationStyle": {
6
6
  "$mulmocast": {
7
- "version": "1.0",
7
+ "version": "1.1",
8
8
  "credit": "closing"
9
9
  },
10
10
  "canvasSize": {
@@ -4,7 +4,7 @@
4
4
  "systemPrompt": "この件について、内容全てを高校生にも分かるように、太郎くん(Student)と先生(Teacher)の会話、という形の台本をArtifactとして作って。ただし要点はしっかりと押さえて。以下に別のトピックに関するサンプルを貼り付けます。このJSONフォーマットに従って。",
5
5
  "presentationStyle": {
6
6
  "$mulmocast": {
7
- "version": "1.0",
7
+ "version": "1.1",
8
8
  "credit": "closing"
9
9
  },
10
10
  "canvasSize": {
@@ -15,11 +15,10 @@
15
15
  "style": "<style>Ghibli style. Student (Taro) is a young teenager with a dark short hair with glasses. Teacher is a middle-aged man with grey hair and moustache.</style>"
16
16
  },
17
17
  "speechParams": {
18
- "provider": "nijivoice",
19
18
  "speakers": {
20
- "Announcer": { "displayName": { "ja": "アナウンサー" }, "voiceId": "3708ad43-cace-486c-a4ca-8fe41186e20c" },
21
- "Student": { "displayName": { "ja": "太郎" }, "voiceId": "a7619e48-bf6a-4f9f-843f-40485651257f" },
22
- "Teacher": { "displayName": { "ja": "先生" }, "voiceId": "bc06c63f-fef6-43b6-92f7-67f919bd5dae" }
19
+ "Announcer": { "provider": "nijivoice", "displayName": { "ja": "アナウンサー" }, "voiceId": "3708ad43-cace-486c-a4ca-8fe41186e20c" },
20
+ "Student": { "provider": "nijivoice", "displayName": { "ja": "太郎" }, "voiceId": "a7619e48-bf6a-4f9f-843f-40485651257f" },
21
+ "Teacher": { "provider": "nijivoice", "displayName": { "ja": "先生" }, "voiceId": "bc06c63f-fef6-43b6-92f7-67f919bd5dae" }
23
22
  }
24
23
  }
25
24
  },
@@ -4,7 +4,7 @@
4
4
  "systemPrompt": "Generate a script for a Youtube shorts of the given topic. The first beat should be a hook, which describes the topic. Another AI will generate images for each beat based on the image prompt of that beat. Movie prompts must be written in English.",
5
5
  "presentationStyle": {
6
6
  "$mulmocast": {
7
- "version": "1.0"
7
+ "version": "1.1"
8
8
  },
9
9
  "canvasSize": {
10
10
  "width": 720,
@@ -4,7 +4,7 @@
4
4
  "systemPrompt": "Generate a script for a movie trailer of the given story. Another AI will generate images for each beat based on the image prompt of that beat. Movie prompts must be written in English.",
5
5
  "presentationStyle": {
6
6
  "$mulmocast": {
7
- "version": "1.0"
7
+ "version": "1.1"
8
8
  },
9
9
  "canvasSize": {
10
10
  "width": 1280,
@@ -9,6 +9,7 @@ import ttsGoogleAgent from "../agents/tts_google_agent.js";
9
9
  import ttsElevenlabsAgent from "../agents/tts_elevenlabs_agent.js";
10
10
  import { fileWriteAgent } from "@graphai/vanilla_node_agents";
11
11
  import { MulmoPresentationStyleMethods } from "../methods/index.js";
12
+ import { text2SpeechProviderSchema, } from "../types/index.js";
12
13
  import { fileCacheAgentFilter } from "../utils/filters.js";
13
14
  import { getAudioArtifactFilePath, getAudioFilePath, getOutputStudioFilePath, resolveDirPath, defaultBGMPath, mkdir, writingMessage } from "../utils/file.js";
14
15
  import { text2hash, localizedText, settings2GraphAIConfig } from "../utils/utils.js";
@@ -30,12 +31,10 @@ const getAudioPath = (context, beat, audioFile) => {
30
31
  return audioFile;
31
32
  };
32
33
  const getAudioParam = (presentationStyle, beat) => {
33
- const voiceId = MulmoPresentationStyleMethods.getVoiceId(presentationStyle, beat);
34
- // Use speaker-specific provider if available, otherwise fall back to script-level provider
35
- const provider = MulmoPresentationStyleMethods.getTTSProvider(presentationStyle, beat);
36
- const speechOptions = MulmoPresentationStyleMethods.getSpeechOptions(presentationStyle, beat);
37
- const model = MulmoPresentationStyleMethods.getTTSModel(presentationStyle, beat);
38
- return { voiceId, provider, speechOptions, model };
34
+ const speaker = MulmoPresentationStyleMethods.getSpeaker(presentationStyle, beat);
35
+ const speechOptions = { ...speaker.speechOptions, ...beat.speechOptions };
36
+ const provider = text2SpeechProviderSchema.parse(speaker.provider);
37
+ return { voiceId: speaker.voiceId, provider, speechOptions, model: speaker.model };
39
38
  };
40
39
  export const getBeatAudioPath = (text, context, beat, lang) => {
41
40
  const audioDirPath = MulmoStudioContextMethods.getAudioDirPath(context);
@@ -143,6 +142,7 @@ const graph_data = {
143
142
  },
144
143
  addBGM: {
145
144
  agent: "addBGMAgent",
145
+ unless: ":context.presentationStyle.audioParams.bgmVolume.equal(0)",
146
146
  inputs: {
147
147
  wait: ":combineFiles",
148
148
  voiceFile: ":audioCombinedFilePath",
@@ -153,6 +153,7 @@ const graph_data = {
153
153
  },
154
154
  },
155
155
  isResult: true,
156
+ defaultValue: {},
156
157
  },
157
158
  title: {
158
159
  agent: "copyAgent",
@@ -181,7 +182,7 @@ export const audioFilePath = (context) => {
181
182
  const getConcurrency = (context) => {
182
183
  // Check if any speaker uses nijivoice or elevenlabs (providers that require concurrency = 1)
183
184
  const hasLimitedConcurrencyProvider = Object.values(context.presentationStyle.speechParams.speakers).some((speaker) => {
184
- const provider = (speaker.provider ?? context.presentationStyle.speechParams.provider);
185
+ const provider = text2SpeechProviderSchema.parse(speaker.provider);
185
186
  return provider2TTSAgent[provider].hasLimitedConcurrency;
186
187
  });
187
188
  return hasLimitedConcurrencyProvider ? 1 : 8;
@@ -1,4 +1,4 @@
1
- import { MulmoStudioContext, MulmoBeat, MulmoCanvasDimension } from "../types/index.js";
1
+ import { MulmoStudioContext, MulmoBeat, MulmoCanvasDimension, MulmoImageParams } from "../types/index.js";
2
2
  export declare const imagePreprocessAgent: (namedInputs: {
3
3
  context: MulmoStudioContext;
4
4
  beat: MulmoBeat;
@@ -12,76 +12,45 @@ export declare const imagePreprocessAgent: (namedInputs: {
12
12
  } | {
13
13
  imagePath: string | undefined;
14
14
  referenceImageForMovie: string | undefined;
15
- imageParams: {
16
- provider: string;
17
- model?: string | undefined;
18
- style?: 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
- };
15
+ imageParams: MulmoImageParams;
40
16
  movieFile: string | undefined;
17
+ soundEffectFile?: string;
18
+ soundEffectPrompt?: string;
19
+ soundEffectModel?: string;
20
+ soundEffectAgentInfo?: {
21
+ agentName: string;
22
+ defaultModel: string;
23
+ };
41
24
  htmlPrompt?: undefined;
42
25
  htmlPath?: undefined;
43
26
  htmlImageSystemPrompt?: undefined;
44
27
  } | {
45
28
  imagePath: string;
46
29
  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
- model?: string | undefined;
62
- style?: 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;
30
+ movieAgentInfo: {
31
+ agent: string;
32
+ movieParams: {
33
+ speed?: number | undefined;
34
+ provider?: string | undefined;
35
+ model?: string | undefined;
36
+ fillOption?: {
37
+ style: "aspectFit" | "aspectFill";
38
+ } | undefined;
39
+ transition?: {
40
+ type: "fade" | "slideout_left";
41
+ duration: number;
42
+ } | undefined;
43
+ };
83
44
  };
45
+ imageParams: MulmoImageParams;
84
46
  movieFile: string | undefined;
47
+ soundEffectFile?: string;
48
+ soundEffectPrompt?: string;
49
+ soundEffectModel?: string;
50
+ soundEffectAgentInfo?: {
51
+ agentName: string;
52
+ defaultModel: string;
53
+ };
85
54
  htmlPrompt?: undefined;
86
55
  htmlPath?: undefined;
87
56
  htmlImageSystemPrompt?: undefined;
@@ -91,44 +60,30 @@ export declare const imagePreprocessAgent: (namedInputs: {
91
60
  imageAgentInfo: import("../types/type.js").Text2ImageAgentInfo;
92
61
  prompt: string;
93
62
  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
- model?: string | undefined;
109
- style?: 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;
63
+ movieAgentInfo: {
64
+ agent: string;
65
+ movieParams: {
66
+ speed?: number | undefined;
67
+ provider?: string | undefined;
68
+ model?: string | undefined;
69
+ fillOption?: {
70
+ style: "aspectFit" | "aspectFill";
71
+ } | undefined;
72
+ transition?: {
73
+ type: "fade" | "slideout_left";
74
+ duration: number;
75
+ } | undefined;
76
+ };
130
77
  };
78
+ imageParams: MulmoImageParams;
131
79
  movieFile: string | undefined;
80
+ soundEffectFile?: string;
81
+ soundEffectPrompt?: string;
82
+ soundEffectModel?: string;
83
+ soundEffectAgentInfo?: {
84
+ agentName: string;
85
+ defaultModel: string;
86
+ };
132
87
  htmlPrompt?: undefined;
133
88
  htmlPath?: undefined;
134
89
  htmlImageSystemPrompt?: undefined;
@@ -1,5 +1,5 @@
1
1
  import { MulmoPresentationStyleMethods, MulmoStudioContextMethods, MulmoBeatMethods } from "../methods/index.js";
2
- import { getBeatPngImagePath, getBeatMoviePath } from "../utils/file.js";
2
+ import { getBeatPngImagePath, getBeatMoviePaths } from "../utils/file.js";
3
3
  import { imagePrompt, htmlImageSystemPrompt } from "../utils/prompt.js";
4
4
  import { renderHTMLToImage } from "../utils/markdown.js";
5
5
  import { GraphAILogger } from "graphai";
@@ -18,25 +18,33 @@ export const imagePreprocessAgent = async (namedInputs) => {
18
18
  return { imagePath, htmlPrompt, htmlPath, htmlImageSystemPrompt: htmlImageSystemPrompt(context.presentationStyle.canvasSize) };
19
19
  }
20
20
  const imageAgentInfo = MulmoPresentationStyleMethods.getImageAgentInfo(context.presentationStyle, beat);
21
+ const moviePaths = getBeatMoviePaths(context, index);
21
22
  const returnValue = {
22
23
  imageParams: imageAgentInfo.imageParams,
23
- movieFile: beat.moviePrompt ? getBeatMoviePath(context, index) : undefined,
24
+ movieFile: beat.moviePrompt ? moviePaths.movieFile : undefined,
24
25
  };
26
+ if (beat.soundEffectPrompt) {
27
+ returnValue.soundEffectAgentInfo = MulmoPresentationStyleMethods.getSoundEffectAgentInfo(context.presentationStyle, beat);
28
+ returnValue.soundEffectModel =
29
+ beat.soundEffectParams?.model ?? context.presentationStyle.soundEffectParams?.model ?? returnValue.soundEffectAgentInfo.defaultModel;
30
+ returnValue.soundEffectFile = moviePaths.soundEffectFile;
31
+ returnValue.soundEffectPrompt = beat.soundEffectPrompt;
32
+ }
25
33
  if (beat.image) {
26
34
  const plugin = MulmoBeatMethods.getPlugin(beat);
27
35
  const pluginPath = plugin.path({ beat, context, imagePath, ...htmlStyle(context, beat) });
28
36
  // undefined prompt indicates that image generation is not needed
29
37
  return { ...returnValue, imagePath: pluginPath, referenceImageForMovie: pluginPath };
30
38
  }
31
- const movieParams = { ...context.presentationStyle.movieParams, ...beat.movieParams };
32
- GraphAILogger.log(`movieParams: ${index}`, movieParams, beat.moviePrompt);
39
+ const movieAgentInfo = MulmoPresentationStyleMethods.getMovieAgentInfo(context.presentationStyle, beat);
40
+ GraphAILogger.log(`movieParams: ${index}`, movieAgentInfo.movieParams, returnValue.soundEffectAgentInfo, "\n", beat.moviePrompt, beat.soundEffectPrompt);
33
41
  if (beat.moviePrompt && !beat.imagePrompt) {
34
- return { ...returnValue, imagePath, imageFromMovie: true, movieParams }; // no image prompt, only movie prompt
42
+ return { ...returnValue, imagePath, imageFromMovie: true, movieAgentInfo }; // no image prompt, only movie prompt
35
43
  }
36
44
  // referenceImages for "edit_image", openai agent.
37
45
  const referenceImages = MulmoBeatMethods.getImageReferenceForImageGenerator(beat, imageRefs);
38
46
  const prompt = imagePrompt(beat, imageAgentInfo.imageParams.style);
39
- return { ...returnValue, imagePath, referenceImageForMovie: imagePath, imageAgentInfo, prompt, referenceImages, movieParams };
47
+ return { ...returnValue, imagePath, referenceImageForMovie: imagePath, imageAgentInfo, prompt, referenceImages, movieAgentInfo };
40
48
  };
41
49
  export const imagePluginAgent = async (namedInputs) => {
42
50
  const { context, beat, index } = namedInputs;