mulmocast 0.1.7 → 1.1.1

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 (75) hide show
  1. package/assets/templates/akira_comic.json +1 -1
  2. package/assets/templates/ani.json +3 -3
  3. package/assets/templates/ani_ja.json +4 -5
  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 +6 -7
  19. package/lib/actions/image_agents.d.ts +46 -76
  20. package/lib/actions/image_agents.js +18 -3
  21. package/lib/actions/images.js +65 -4
  22. package/lib/actions/movie.js +3 -2
  23. package/lib/agents/index.d.ts +3 -1
  24. package/lib/agents/index.js +3 -1
  25. package/lib/agents/lipsync_replicate_agent.d.ts +5 -0
  26. package/lib/agents/lipsync_replicate_agent.js +57 -0
  27. package/lib/agents/movie_replicate_agent.js +17 -5
  28. package/lib/agents/sound_effect_replicate_agent.d.ts +5 -0
  29. package/lib/agents/sound_effect_replicate_agent.js +59 -0
  30. package/lib/data/index.d.ts +2 -0
  31. package/lib/data/index.js +2 -0
  32. package/lib/data/promptTemplates.d.ts +695 -0
  33. package/lib/data/promptTemplates.js +957 -0
  34. package/lib/data/scriptTemplates.d.ts +233 -0
  35. package/lib/data/scriptTemplates.js +580 -0
  36. package/lib/index.browser.d.ts +2 -1
  37. package/lib/index.browser.js +2 -1
  38. package/lib/mcp/server.js +2 -2
  39. package/lib/methods/index.d.ts +1 -0
  40. package/lib/methods/index.js +1 -0
  41. package/lib/methods/mulmo_presentation_style.d.ts +18 -5
  42. package/lib/methods/mulmo_presentation_style.js +31 -20
  43. package/lib/methods/mulmo_script.d.ts +4 -0
  44. package/lib/methods/mulmo_script.js +31 -0
  45. package/lib/tools/story_to_script.js +2 -2
  46. package/lib/types/agent.d.ts +19 -0
  47. package/lib/types/schema.d.ts +628 -246
  48. package/lib/types/schema.js +31 -12
  49. package/lib/types/type.d.ts +2 -3
  50. package/lib/utils/assets.d.ts +18 -0
  51. package/lib/utils/assets.js +101 -0
  52. package/lib/utils/context.d.ts +40 -12
  53. package/lib/utils/context.js +3 -1
  54. package/lib/utils/file.d.ts +12 -4
  55. package/lib/utils/file.js +48 -24
  56. package/lib/utils/preprocess.d.ts +30 -11
  57. package/lib/utils/preprocess.js +7 -5
  58. package/lib/utils/provider2agent.d.ts +30 -1
  59. package/lib/utils/provider2agent.js +86 -0
  60. package/lib/utils/utils.js +6 -0
  61. package/package.json +8 -4
  62. package/scripts/templates/business.json +1 -1
  63. package/scripts/templates/children_book.json +1 -1
  64. package/scripts/templates/coding.json +1 -1
  65. package/scripts/templates/html.json +1 -1
  66. package/scripts/templates/image_prompt_only_template.json +1 -1
  67. package/scripts/templates/image_prompts_template.json +1 -1
  68. package/scripts/templates/image_refs.json +1 -1
  69. package/scripts/templates/movie_prompts_no_text_template.json +1 -1
  70. package/scripts/templates/movie_prompts_template.json +1 -1
  71. package/scripts/templates/presentation.json +1 -1
  72. package/scripts/templates/sensei_and_taro.json +1 -1
  73. package/scripts/templates/shorts_template.json +1 -1
  74. package/scripts/templates/text_only_template.json +1 -1
  75. package/scripts/templates/voice_over.json +1 -1
@@ -1,7 +1,8 @@
1
1
  import "dotenv/config";
2
+ import { isNull } from "graphai";
2
3
  import { userAssert } from "../utils/utils.js";
3
4
  import { text2ImageProviderSchema, text2HtmlImageProviderSchema, text2MovieProviderSchema, text2SpeechProviderSchema, mulmoCanvasDimensionSchema, } from "../types/schema.js";
4
- import { provider2ImageAgent, provider2MovieAgent, provider2LLMAgent } from "../utils/provider2agent.js";
5
+ import { provider2ImageAgent, provider2MovieAgent, provider2LLMAgent, provider2SoundEffectAgent, provider2LipSyncAgent, defaultProviders, } from "../utils/provider2agent.js";
5
6
  const defaultTextSlideStyles = [
6
7
  '*,*::before,*::after{box-sizing:border-box}body,h1,h2,h3,h4,p,figure,blockquote,dl,dd{margin:0}ul[role="list"],ol[role="list"]{list-style:none}html:focus-within{scroll-behavior:smooth}body{min-height:100vh;text-rendering:optimizeSpeed;line-height:1.5}a:not([class]){text-decoration-skip-ink:auto}img,picture{max-width:100%;display:block}input,button,textarea,select{font:inherit}@media(prefers-reduced-motion:reduce){html:focus-within{scroll-behavior:auto}*,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important;scroll-behavior:auto !important}}',
7
8
  "body { margin: 60px; margin-top: 40px; color:#333; font-size: 30px; font-family: Arial, sans-serif; box-sizing: border-box; height: 100vh }",
@@ -20,14 +21,10 @@ export const MulmoPresentationStyleMethods = {
20
21
  getCanvasSize(presentationStyle) {
21
22
  return mulmoCanvasDimensionSchema.parse(presentationStyle.canvasSize);
22
23
  },
23
- getSpeechProvider(presentationStyle) {
24
- return text2SpeechProviderSchema.parse(presentationStyle.speechParams?.provider);
25
- },
26
24
  getAllSpeechProviders(presentationStyle) {
27
25
  const providers = new Set();
28
- const defaultProvider = this.getSpeechProvider(presentationStyle);
29
26
  Object.values(presentationStyle.speechParams.speakers).forEach((speaker) => {
30
- const provider = speaker.provider ?? defaultProvider;
27
+ const provider = text2SpeechProviderSchema.parse(speaker.provider);
31
28
  providers.add(provider);
32
29
  });
33
30
  return providers;
@@ -39,27 +36,27 @@ export const MulmoPresentationStyleMethods = {
39
36
  // This code allows us to support both string and array of strings for cssStyles
40
37
  return [...defaultTextSlideStyles, ...[styles], ...[extraStyles]].flat().join("\n");
41
38
  },
42
- getSpeechOptions(presentationStyle, beat) {
43
- return { ...presentationStyle.speechParams.speakers[beat.speaker].speechOptions, ...beat.speechOptions };
39
+ getDefaultSpeaker(presentationStyle) {
40
+ const speakers = presentationStyle.speechParams.speakers ?? {};
41
+ const keys = Object.keys(speakers).sort();
42
+ userAssert(keys.length !== 0, "presentationStyle.speechParams.speakers is not set!!");
43
+ const defaultSpeaker = keys.find((key) => speakers[key].isDefault);
44
+ if (!isNull(defaultSpeaker)) {
45
+ return defaultSpeaker;
46
+ }
47
+ return keys[0];
44
48
  },
45
49
  getSpeaker(presentationStyle, beat) {
46
50
  userAssert(!!presentationStyle?.speechParams?.speakers, "presentationStyle.speechParams.speakers is not set!!");
47
- userAssert(!!beat?.speaker, "beat.speaker is not set");
48
- const speaker = presentationStyle.speechParams.speakers[beat.speaker];
49
- userAssert(!!speaker, `speaker is not set: speaker "${beat.speaker}"`);
51
+ const speakerId = beat?.speaker ?? MulmoPresentationStyleMethods.getDefaultSpeaker(presentationStyle);
52
+ userAssert(!!speakerId, "beat.speaker and default speaker is not set");
53
+ const speaker = presentationStyle.speechParams.speakers[speakerId];
54
+ userAssert(!!speaker, `speaker is not set: speaker "${speakerId}"`);
50
55
  return speaker;
51
56
  },
52
- getTTSProvider(presentationStyle, beat) {
53
- const speaker = MulmoPresentationStyleMethods.getSpeaker(presentationStyle, beat);
54
- return speaker.provider ?? presentationStyle.speechParams.provider;
55
- },
56
57
  getTTSModel(presentationStyle, beat) {
57
58
  const speaker = MulmoPresentationStyleMethods.getSpeaker(presentationStyle, beat);
58
- return speaker.model ?? presentationStyle.speechParams.model;
59
- },
60
- getVoiceId(presentationStyle, beat) {
61
- const speaker = MulmoPresentationStyleMethods.getSpeaker(presentationStyle, beat);
62
- return speaker.voiceId;
59
+ return speaker.model;
63
60
  },
64
61
  getText2ImageProvider(provider) {
65
62
  return text2ImageProviderSchema.parse(provider);
@@ -89,6 +86,20 @@ export const MulmoPresentationStyleMethods = {
89
86
  movieParams,
90
87
  };
91
88
  },
89
+ getSoundEffectAgentInfo(presentationStyle, beat) {
90
+ const soundEffectProvider = (beat.soundEffectParams?.provider ??
91
+ presentationStyle.soundEffectParams?.provider ??
92
+ defaultProviders.soundEffect);
93
+ const agentInfo = provider2SoundEffectAgent[soundEffectProvider];
94
+ return agentInfo;
95
+ },
96
+ getLipSyncAgentInfo(presentationStyle, beat) {
97
+ const lipSyncProvider = (beat.lipSyncParams?.provider ??
98
+ presentationStyle.lipSyncParams?.provider ??
99
+ defaultProviders.lipSync);
100
+ const agentInfo = provider2LipSyncAgent[lipSyncProvider];
101
+ return agentInfo;
102
+ },
92
103
  getConcurrency(presentationStyle) {
93
104
  const imageAgentInfo = MulmoPresentationStyleMethods.getImageAgentInfo(presentationStyle);
94
105
  if (imageAgentInfo.imageParams.provider === "openai") {
@@ -0,0 +1,4 @@
1
+ import { MulmoScript } from "../types/index.js";
2
+ export declare const MulmoScriptMethods: {
3
+ validate(script: any): MulmoScript;
4
+ };
@@ -0,0 +1,31 @@
1
+ import { mulmoScriptSchema } from "../types/index.js";
2
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3
+ const validate_1_0 = (script) => {
4
+ if (script.speechParams?.provider) {
5
+ if (typeof script.speechParams.speakers === "object") {
6
+ Object.keys(script.speechParams.speakers).forEach((speakerId) => {
7
+ const speaker = script.speechParams.speakers[speakerId];
8
+ if (!speaker.provider) {
9
+ speaker.provider = script.speechParams.provider;
10
+ }
11
+ });
12
+ }
13
+ delete script.speechParams.provider;
14
+ }
15
+ return script;
16
+ };
17
+ const validators = [{ from: "1.0", to: "1.1", validator: validate_1_0 }];
18
+ export const MulmoScriptMethods = {
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ validate(script) {
21
+ const validatedScript = validators.reduce((acc, validator) => {
22
+ if (acc.$mulmocast.version === validator.from) {
23
+ const validated = validator.validator(acc);
24
+ validated.$mulmocast.version = validator.to;
25
+ return validated;
26
+ }
27
+ return acc;
28
+ }, script);
29
+ return mulmoScriptSchema.parse(validatedScript);
30
+ },
31
+ };
@@ -1,4 +1,4 @@
1
- import { getTemplateFilePath, readAndParseJson, readScriptTemplateFile, writingMessage } from "../utils/file.js";
1
+ import { getPromptTemplateFilePath, readAndParseJson, readScriptTemplateFile, writingMessage } from "../utils/file.js";
2
2
  import { mulmoScriptSchema, mulmoScriptTemplateSchema } from "../types/schema.js";
3
3
  import { GraphAI, GraphAILogger } from "graphai";
4
4
  import { openAIAgent } from "@graphai/openai_agent";
@@ -249,7 +249,7 @@ const generateScriptPrompt = async (template, beatsPerScene, story) => {
249
249
  return storyToScriptPrompt(script, beatsPerScene, story);
250
250
  };
251
251
  export const storyToScript = async ({ story, beatsPerScene, templateName, outdir, fileName, llm, llmModel, generateMode, }) => {
252
- const template = readAndParseJson(getTemplateFilePath(templateName), mulmoScriptTemplateSchema);
252
+ const template = readAndParseJson(getPromptTemplateFilePath(templateName), mulmoScriptTemplateSchema);
253
253
  const { agent, model, max_tokens } = llmPair(llm, llmModel);
254
254
  const beatsPrompt = await generateBeatsPrompt(template, beatsPerScene, story);
255
255
  const scriptInfoPrompt = await generateScriptInfoPrompt(template, story);
@@ -58,8 +58,27 @@ export type ReplicateMovieAgentParams = {
58
58
  };
59
59
  duration?: number;
60
60
  };
61
+ export type ReplicateSoundEffectAgentParams = {
62
+ model: `${string}/${string}` | undefined;
63
+ duration?: number;
64
+ };
65
+ export type SoundEffectAgentInputs = AgentPromptInputs & {
66
+ soundEffectFile: string;
67
+ movieFile: string;
68
+ };
69
+ export type ReplicateLipSyncAgentParams = {
70
+ model: `${string}/${string}` | undefined;
71
+ duration?: number;
72
+ };
73
+ export type LipSyncAgentInputs = {
74
+ lipSyncFile: string;
75
+ movieFile: string;
76
+ audioFile: string;
77
+ };
61
78
  export type GoogleMovieAgentConfig = GoogleImageAgentConfig;
62
79
  export type ReplicateMovieAgentConfig = AgentConfig;
80
+ export type ReplicateSoundEffectAgentConfig = AgentConfig;
81
+ export type ReplicateLipSyncAgentConfig = AgentConfig;
63
82
  export type TTSAgentParams = {
64
83
  suppressError: boolean;
65
84
  voice: string;