mulmocast 2.1.23 → 2.1.25

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.
@@ -0,0 +1,284 @@
1
+ export const styles = [
2
+ {
3
+ filename: 'akira_comic',
4
+ presentationStyle: {
5
+ '$mulmocast': {
6
+ credit: 'closing',
7
+ version: '1.1'
8
+ },
9
+ canvasSize: {
10
+ height: 1024,
11
+ width: 1536
12
+ },
13
+ imageParams: {
14
+ images: {
15
+ girl: {
16
+ source: {
17
+ kind: 'url',
18
+ url: 'https://raw.githubusercontent.com/receptron/mulmocast-media/refs/heads/main/characters/akira_presenter.png'
19
+ },
20
+ type: 'image'
21
+ }
22
+ },
23
+ style: '<style>AKIRA aesthetic.</style>'
24
+ }
25
+ }
26
+ },
27
+ {
28
+ filename: 'ani',
29
+ presentationStyle: {
30
+ '$mulmocast': {
31
+ credit: 'closing',
32
+ version: '1.1'
33
+ },
34
+ audioParams: {
35
+ bgm: {
36
+ kind: 'url',
37
+ url: 'https://github.com/receptron/mulmocast-media/raw/refs/heads/main/bgms/morning001.mp3'
38
+ }
39
+ },
40
+ canvasSize: {
41
+ height: 1536,
42
+ width: 1024
43
+ },
44
+ imageParams: {
45
+ images: {
46
+ ani: {
47
+ source: {
48
+ kind: 'url',
49
+ url: 'https://raw.githubusercontent.com/receptron/mulmocast-media/refs/heads/main/characters/ani.png'
50
+ },
51
+ type: 'image'
52
+ }
53
+ },
54
+ model: 'gemini-2.5-flash-image',
55
+ provider: 'google',
56
+ 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>'
57
+ },
58
+ movieParams: {
59
+ model: 'bytedance/seedance-1-lite',
60
+ provider: 'replicate'
61
+ },
62
+ speechParams: {
63
+ speakers: {
64
+ Presenter: {
65
+ provider: 'gemini',
66
+ speechOptions: {
67
+ instruction: 'Speak in a slightly high-pitched, curt tone with sudden flustered shifts—like a tsundere anime girl.'
68
+ },
69
+ voiceId: 'Leda'
70
+ }
71
+ }
72
+ }
73
+ }
74
+ },
75
+ {
76
+ filename: 'children_book',
77
+ presentationStyle: {
78
+ '$mulmocast': {
79
+ credit: 'closing',
80
+ version: '1.1'
81
+ },
82
+ canvasSize: {
83
+ height: 1024,
84
+ width: 1536
85
+ },
86
+ imageParams: {
87
+ style: 'A hand-drawn style illustration with a warm, nostalgic atmosphere. The background is rich with natural scenery—lush forests, cloudy skies, and traditional Japanese architecture. Characters have expressive eyes, soft facial features, and are portrayed with gentle lighting and subtle shading. The color palette is muted yet vivid, using earthy tones and watercolor-like textures. The overall scene feels magical and peaceful, with a sense of quiet wonder and emotional depth, reminiscent of classic 1980s and 1990s Japanese animation.'
88
+ }
89
+ }
90
+ },
91
+ {
92
+ filename: 'comic_strips',
93
+ presentationStyle: {
94
+ '$mulmocast': {
95
+ credit: 'closing',
96
+ version: '1.1'
97
+ },
98
+ canvasSize: {
99
+ height: 1024,
100
+ width: 1536
101
+ },
102
+ imageParams: {
103
+ style: '<style>A multi panel comic strips. 1990s American workplace humor. Clean, minimalist line art with muted colors. One character is a nerdy office worker with glasses</style>'
104
+ }
105
+ }
106
+ },
107
+ {
108
+ filename: 'drslump_comic',
109
+ presentationStyle: {
110
+ '$mulmocast': {
111
+ credit: 'closing',
112
+ version: '1.1'
113
+ },
114
+ canvasSize: {
115
+ height: 1024,
116
+ width: 1536
117
+ },
118
+ imageParams: {
119
+ images: {
120
+ girl: {
121
+ source: {
122
+ kind: 'url',
123
+ url: 'https://raw.githubusercontent.com/receptron/mulmocast-media/refs/heads/main/characters/slump_presenter.png'
124
+ },
125
+ type: 'image'
126
+ }
127
+ },
128
+ style: '<style>Dragon Ball/Dr. Slump aesthetic.</style>'
129
+ }
130
+ }
131
+ },
132
+ {
133
+ filename: 'ghibli_comic',
134
+ presentationStyle: {
135
+ '$mulmocast': {
136
+ credit: 'closing',
137
+ version: '1.1'
138
+ },
139
+ canvasSize: {
140
+ height: 1024,
141
+ width: 1536
142
+ },
143
+ imageParams: {
144
+ images: {
145
+ presenter: {
146
+ source: {
147
+ kind: 'url',
148
+ url: 'https://raw.githubusercontent.com/receptron/mulmocast-media/refs/heads/main/characters/ghibli_presenter.png'
149
+ },
150
+ type: 'image'
151
+ }
152
+ },
153
+ style: '<style>Ghibli style</style>'
154
+ }
155
+ }
156
+ },
157
+ {
158
+ filename: 'ghibli_shorts',
159
+ presentationStyle: {
160
+ '$mulmocast': {
161
+ credit: 'closing',
162
+ version: '1.1'
163
+ },
164
+ canvasSize: {
165
+ height: 1536,
166
+ width: 1024
167
+ },
168
+ imageParams: {
169
+ images: {
170
+ presenter: {
171
+ source: {
172
+ kind: 'url',
173
+ url: 'https://raw.githubusercontent.com/receptron/mulmocast-media/refs/heads/main/characters/ghibli_presenter.jpg'
174
+ },
175
+ type: 'image'
176
+ }
177
+ },
178
+ style: '<style>Ghibli style</style>'
179
+ },
180
+ speechParams: {
181
+ provider: 'openai',
182
+ speakers: {
183
+ Presenter: {
184
+ speechOptions: {
185
+ instruction: 'speak very fast'
186
+ },
187
+ voiceId: 'shimmer'
188
+ }
189
+ }
190
+ }
191
+ }
192
+ },
193
+ {
194
+ filename: 'ghost_comic',
195
+ presentationStyle: {
196
+ '$mulmocast': {
197
+ credit: 'closing',
198
+ version: '1.1'
199
+ },
200
+ canvasSize: {
201
+ height: 1024,
202
+ width: 1536
203
+ },
204
+ imageParams: {
205
+ images: {
206
+ optimus: {
207
+ source: {
208
+ kind: 'url',
209
+ url: 'https://raw.githubusercontent.com/receptron/mulmocast-media/refs/heads/main/characters/optimus.png'
210
+ },
211
+ type: 'image'
212
+ },
213
+ presenter: {
214
+ source: {
215
+ kind: 'url',
216
+ url: 'https://raw.githubusercontent.com/receptron/mulmocast-media/refs/heads/main/characters/ghost_presenter.png'
217
+ },
218
+ type: 'image'
219
+ }
220
+ },
221
+ style: '<style>Ghost in the shell aesthetic.</style>'
222
+ }
223
+ }
224
+ },
225
+ {
226
+ filename: 'leda',
227
+ presentationStyle: {
228
+ '$mulmocast': {
229
+ credit: 'closing',
230
+ version: '1.1'
231
+ },
232
+ audioParams: {
233
+ bgm: {
234
+ kind: 'url',
235
+ url: 'https://github.com/receptron/mulmocast-media/raw/refs/heads/main/bgms/morning001.mp3'
236
+ }
237
+ },
238
+ canvasSize: {
239
+ height: 1536,
240
+ width: 1024
241
+ },
242
+ imageParams: {
243
+ model: 'gemini-2.5-flash-image',
244
+ provider: 'google'
245
+ },
246
+ speechParams: {
247
+ speakers: {
248
+ Presenter: {
249
+ provider: 'gemini',
250
+ speechOptions: {
251
+ instruction: 'Speak like a professional news presenter.'
252
+ },
253
+ voiceId: 'Leda'
254
+ }
255
+ }
256
+ }
257
+ }
258
+ },
259
+ {
260
+ filename: 'onepiece_comic',
261
+ presentationStyle: {
262
+ '$mulmocast': {
263
+ credit: 'closing',
264
+ version: '1.1'
265
+ },
266
+ canvasSize: {
267
+ height: 1024,
268
+ width: 1536
269
+ },
270
+ imageParams: {
271
+ images: {
272
+ presenter: {
273
+ source: {
274
+ kind: 'url',
275
+ url: 'https://raw.githubusercontent.com/receptron/mulmocast-media/refs/heads/main/characters/onepiece_presenter.png'
276
+ },
277
+ type: 'image'
278
+ }
279
+ },
280
+ style: '<style>One Piece aesthetic.</style>'
281
+ }
282
+ }
283
+ }
284
+ ];
@@ -171,6 +171,8 @@ export declare const MulmoPresentationStyleMethods: {
171
171
  type: "custom";
172
172
  filter: string;
173
173
  })[] | undefined;
174
+ vertexai_project?: string | undefined;
175
+ vertexai_location?: string | undefined;
174
176
  speed?: number | undefined;
175
177
  };
176
178
  keyName: string;
@@ -0,0 +1,21 @@
1
+ import { type ZodSafeParseResult } from "zod";
2
+ import type { MulmoScript } from "../types/type.js";
3
+ type PartialMulmoScript = Record<string, unknown>;
4
+ /**
5
+ * Add $mulmocast version if not present
6
+ */
7
+ export declare const addMulmocastVersion: (data: PartialMulmoScript) => PartialMulmoScript;
8
+ /**
9
+ * Merge input data with template (input takes precedence)
10
+ */
11
+ export declare const mergeWithTemplate: (data: PartialMulmoScript, template: MulmoScript) => PartialMulmoScript;
12
+ export type CompleteScriptResult = ZodSafeParseResult<MulmoScript>;
13
+ /**
14
+ * Complete a partial MulmoScript with schema defaults and optional template
15
+ */
16
+ export declare const completeScript: (data: PartialMulmoScript, templateName?: string) => CompleteScriptResult;
17
+ /**
18
+ * Check if template exists
19
+ */
20
+ export declare const templateExists: (templateName: string) => boolean;
21
+ export {};
@@ -0,0 +1,47 @@
1
+ import { mulmoScriptSchema } from "../types/schema.js";
2
+ import { getScriptFromPromptTemplate } from "../utils/file.js";
3
+ import { currentMulmoScriptVersion } from "../types/const.js";
4
+ /**
5
+ * Add $mulmocast version if not present
6
+ */
7
+ export const addMulmocastVersion = (data) => {
8
+ if (data.$mulmocast) {
9
+ return data;
10
+ }
11
+ return {
12
+ ...data,
13
+ $mulmocast: { version: currentMulmoScriptVersion },
14
+ };
15
+ };
16
+ const deepMergeKeys = ["speechParams", "imageParams", "movieParams", "audioParams"];
17
+ /**
18
+ * Merge input data with template (input takes precedence)
19
+ */
20
+ export const mergeWithTemplate = (data, template) => {
21
+ const merged = { ...template, ...data };
22
+ deepMergeKeys.forEach((key) => {
23
+ if (template[key] && data[key]) {
24
+ merged[key] = { ...template[key], ...data[key] };
25
+ }
26
+ });
27
+ return merged;
28
+ };
29
+ /**
30
+ * Complete a partial MulmoScript with schema defaults and optional template
31
+ */
32
+ export const completeScript = (data, templateName) => {
33
+ const withVersion = addMulmocastVersion(data);
34
+ const withTemplate = templateName
35
+ ? (() => {
36
+ const template = getScriptFromPromptTemplate(templateName);
37
+ return template ? mergeWithTemplate(withVersion, template) : withVersion;
38
+ })()
39
+ : withVersion;
40
+ return mulmoScriptSchema.safeParse(withTemplate);
41
+ };
42
+ /**
43
+ * Check if template exists
44
+ */
45
+ export const templateExists = (templateName) => {
46
+ return getScriptFromPromptTemplate(templateName) !== undefined;
47
+ };
@@ -14,7 +14,7 @@ import { browserlessCacheGenerator } from "../utils/filters.js";
14
14
  import { mulmoScriptSchema, urlsSchema } from "../types/schema.js";
15
15
  import { cliLoadingPlugin } from "../utils/plugins.js";
16
16
  import { graphDataScriptFromUrlPrompt } from "../utils/prompt.js";
17
- import { llmPair } from "../utils/utils.js";
17
+ import { llmPair, settings2GraphAIConfig } from "../utils/utils.js";
18
18
  import { readFileSync } from "fs";
19
19
  dotenv.config({ quiet: true });
20
20
  const vanillaAgents = agents.default ?? agents;
@@ -220,6 +220,7 @@ export const createMulmoScriptFromUrl = async ({ urls, templateName, outDirPath,
220
220
  },
221
221
  ];
222
222
  const { agent, model, max_tokens } = llmPair(llm, llm_model);
223
+ const config = settings2GraphAIConfig(undefined, process.env);
223
224
  const graph = new GraphAI(graphData, {
224
225
  ...vanillaAgents,
225
226
  openAIAgent,
@@ -229,7 +230,7 @@ export const createMulmoScriptFromUrl = async ({ urls, templateName, outDirPath,
229
230
  browserlessAgent,
230
231
  validateSchemaAgent,
231
232
  fileWriteAgent,
232
- }, { agentFilters });
233
+ }, { agentFilters, config });
233
234
  graph.injectValue("urls", parsedUrls);
234
235
  graph.injectValue("systemPrompt", readTemplatePrompt(templateName));
235
236
  graph.injectValue("outdir", outDirPath);
@@ -251,6 +252,7 @@ export const createMulmoScriptFromFile = async (fileName, { templateName, outDir
251
252
  const filePath = path.resolve(process.cwd(), fileName);
252
253
  const text = readFileSync(filePath, "utf-8");
253
254
  const { agent, model, max_tokens } = llmPair(llm, llm_model);
255
+ const config = settings2GraphAIConfig(undefined, process.env);
254
256
  const graph = new GraphAI(graphDataText, {
255
257
  ...vanillaAgents,
256
258
  openAIAgent,
@@ -259,7 +261,7 @@ export const createMulmoScriptFromFile = async (fileName, { templateName, outDir
259
261
  groqAgent,
260
262
  validateSchemaAgent,
261
263
  fileWriteAgent,
262
- });
264
+ }, { config });
263
265
  graph.injectValue("sourceText", { text });
264
266
  graph.injectValue("systemPrompt", readTemplatePrompt(templateName));
265
267
  graph.injectValue("outdir", outDirPath);
@@ -13,7 +13,7 @@ import { browserlessCacheGenerator } from "../utils/filters.js";
13
13
  import { mulmoScriptSchema } from "../types/index.js";
14
14
  import { browserlessAgent } from "@graphai/browserless_agent";
15
15
  import validateSchemaAgent from "../agents/validate_schema_agent.js";
16
- import { llmPair } from "../utils/utils.js";
16
+ import { llmPair, settings2GraphAIConfig } from "../utils/utils.js";
17
17
  import { interactiveClarificationPrompt, prefixPrompt } from "../utils/prompt.js";
18
18
  // import { cliLoadingPlugin } from "../utils/plugins.js";
19
19
  dotenv.config({ quiet: true });
@@ -231,7 +231,8 @@ export const createMulmoScriptInteractively = async ({ outDirPath, cacheDirPath,
231
231
  nodeIds: ["chatAgent"],
232
232
  },
233
233
  ];
234
- const graph = new GraphAI(graphData, { ...vanillaAgents, anthropicAgent, geminiAgent, groqAgent, openAIAgent, textInputAgent, fileWriteAgent, validateSchemaAgent }, { agentFilters });
234
+ const config = settings2GraphAIConfig(undefined, process.env);
235
+ const graph = new GraphAI(graphData, { ...vanillaAgents, anthropicAgent, geminiAgent, groqAgent, openAIAgent, textInputAgent, fileWriteAgent, validateSchemaAgent }, { agentFilters, config });
235
236
  const prompt = readTemplatePrompt(templateName);
236
237
  graph.injectValue("messages", [
237
238
  {
@@ -9,7 +9,7 @@ import * as agents from "@graphai/vanilla";
9
9
  import { graphDataScriptGeneratePrompt, sceneToBeatsPrompt, storyToScriptInfoPrompt, storyToScriptPrompt } from "../utils/prompt.js";
10
10
  import { fileWriteAgent } from "@graphai/vanilla_node_agents";
11
11
  import validateSchemaAgent from "../agents/validate_schema_agent.js";
12
- import { llmPair } from "../utils/utils.js";
12
+ import { llmPair, settings2GraphAIConfig } from "../utils/utils.js";
13
13
  import { storyToScriptGenerateMode } from "../types/const.js";
14
14
  import { cliLoadingPlugin } from "../utils/plugins.js";
15
15
  const vanillaAgents = agents.default ?? agents;
@@ -255,7 +255,8 @@ export const storyToScript = async ({ story, beatsPerScene, templateName, outdir
255
255
  const scriptInfoPrompt = await generateScriptInfoPrompt(template, story);
256
256
  const scriptPrompt = await generateScriptPrompt(template, beatsPerScene, story);
257
257
  const graphData = generateMode === storyToScriptGenerateMode.stepWise ? stepWiseGraphData : oneStepGraphData;
258
- const graph = new GraphAI(graphData, { ...vanillaAgents, openAIAgent, anthropicAgent, geminiAgent, groqAgent, fileWriteAgent, validateSchemaAgent });
258
+ const config = settings2GraphAIConfig(undefined, process.env);
259
+ const graph = new GraphAI(graphData, { ...vanillaAgents, openAIAgent, anthropicAgent, geminiAgent, groqAgent, fileWriteAgent, validateSchemaAgent }, { config });
259
260
  if (generateMode === storyToScriptGenerateMode.stepWise) {
260
261
  graph.injectValue("scenes", story.scenes);
261
262
  graph.injectValue("beatsPrompt", beatsPrompt);
@@ -39,6 +39,8 @@ export type ImageAgentParams = {
39
39
  width: number;
40
40
  height: number;
41
41
  };
42
+ vertexai_project?: string;
43
+ vertexai_location?: string;
42
44
  };
43
45
  export type OpenAIImageAgentParams = ImageAgentParams & {
44
46
  moderation: OpenAIImageModeration | null | undefined;
@@ -74,6 +76,8 @@ export type MovieAgentInputs = AgentPromptInputs & {
74
76
  };
75
77
  export type GoogleMovieAgentParams = ImageAgentParams & {
76
78
  duration?: number;
79
+ vertexai_project?: string;
80
+ vertexai_location?: string;
77
81
  };
78
82
  export type ReplicateMovieAgentParams = {
79
83
  model: `${string}/${string}` | undefined;
@@ -155,7 +155,7 @@ export declare const provider2LLMAgent: {
155
155
  readonly agentName: "geminiAgent";
156
156
  readonly defaultModel: "gemini-2.5-flash";
157
157
  readonly max_tokens: 8192;
158
- readonly models: readonly ["gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-lite"];
158
+ readonly models: readonly ["gemini-3-pro-preview", "gemini-3-flash-preview", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-lite"];
159
159
  readonly keyName: "GEMINI_API_KEY";
160
160
  };
161
161
  readonly groq: {
@@ -56,7 +56,13 @@ export const provider2ImageAgent = {
56
56
  google: {
57
57
  agentName: "imageGenAIAgent",
58
58
  defaultModel: "gemini-2.5-flash-image",
59
- models: ["imagen-4.0-generate-preview-06-06", "imagen-4.0-ultra-generate-preview-06-06", "gemini-2.5-flash-image", "gemini-3-pro-image-preview"],
59
+ models: [
60
+ "imagen-4.0-generate-001",
61
+ "imagen-4.0-ultra-generate-001",
62
+ "imagen-4.0-fast-generate-001",
63
+ "gemini-2.5-flash-image",
64
+ "gemini-3-pro-image-preview",
65
+ ],
60
66
  keyName: "GEMINI_API_KEY",
61
67
  },
62
68
  replicate: {
@@ -283,7 +289,7 @@ export const provider2LLMAgent = {
283
289
  agentName: "geminiAgent",
284
290
  defaultModel: "gemini-2.5-flash",
285
291
  max_tokens: 8192,
286
- models: ["gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-lite"],
292
+ models: ["gemini-3-pro-preview", "gemini-3-flash-preview", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-lite"],
287
293
  keyName: "GEMINI_API_KEY",
288
294
  },
289
295
  groq: {