mulmocast 0.0.2 → 0.0.3
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/README.md +27 -9
- package/assets/font/NotoSansJP-Regular.ttf +0 -0
- package/assets/html/chart.html +1 -10
- package/assets/html/mermaid.html +1 -13
- package/assets/templates/business.json +16 -27
- package/assets/templates/coding.json +58 -21
- package/lib/actions/audio.d.ts +1 -1
- package/lib/actions/audio.js +43 -27
- package/lib/actions/images.js +20 -26
- package/lib/actions/index.d.ts +5 -0
- package/lib/actions/index.js +5 -0
- package/lib/actions/movie.d.ts +9 -1
- package/lib/actions/movie.js +97 -38
- package/lib/actions/pdf.d.ts +2 -0
- package/lib/actions/pdf.js +211 -0
- package/lib/actions/pdf2.d.ts +2 -0
- package/lib/actions/pdf2.js +203 -0
- package/lib/actions/translate.js +22 -9
- package/lib/agents/anthropic_agent.d.ts +23 -0
- package/lib/agents/anthropic_agent.js +162 -0
- package/lib/agents/combine_audio_files_agent.js +13 -22
- package/lib/agents/nested_agent.d.ts +9 -0
- package/lib/agents/nested_agent.js +138 -0
- package/lib/cli/args.d.ts +3 -1
- package/lib/cli/args.js +49 -34
- package/lib/cli/cli.d.ts +14 -0
- package/lib/cli/cli.js +48 -46
- package/lib/cli/tool-args.d.ts +2 -0
- package/lib/cli/tool-args.js +12 -2
- package/lib/cli/tool-cli.js +6 -4
- package/lib/methods/index.d.ts +1 -0
- package/lib/methods/index.js +1 -0
- package/lib/methods/mulmo_media_source.d.ts +4 -0
- package/lib/methods/mulmo_media_source.js +21 -0
- package/lib/methods/mulmo_script.d.ts +2 -6
- package/lib/methods/mulmo_script.js +12 -5
- package/lib/tools/create_mulmo_script_interactively.d.ts +1 -1
- package/lib/tools/create_mulmo_script_interactively.js +61 -20
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.js +1 -0
- package/lib/types/schema.d.ts +3626 -3162
- package/lib/types/schema.js +75 -41
- package/lib/types/type.d.ts +28 -1
- package/lib/utils/const.d.ts +2 -0
- package/lib/utils/const.js +2 -0
- package/lib/utils/file.d.ts +4 -1
- package/lib/utils/file.js +15 -1
- package/lib/utils/filters.js +1 -1
- package/lib/utils/image_plugins/chart.d.ts +3 -0
- package/lib/utils/image_plugins/chart.js +18 -0
- package/lib/utils/image_plugins/image.d.ts +2 -0
- package/lib/utils/image_plugins/image.js +3 -0
- package/lib/utils/image_plugins/index.d.ts +7 -0
- package/lib/utils/image_plugins/index.js +7 -0
- package/lib/utils/image_plugins/markdown.d.ts +3 -0
- package/lib/utils/image_plugins/markdown.js +11 -0
- package/lib/utils/image_plugins/mermaid.d.ts +3 -0
- package/lib/utils/image_plugins/mermaid.js +21 -0
- package/lib/utils/image_plugins/movie.d.ts +2 -0
- package/lib/utils/image_plugins/movie.js +3 -0
- package/lib/utils/image_plugins/source.d.ts +4 -0
- package/lib/utils/image_plugins/source.js +15 -0
- package/lib/utils/image_plugins/text_slide.d.ts +3 -0
- package/lib/utils/image_plugins/text_slide.js +12 -0
- package/lib/utils/image_plugins/type_guards.d.ts +6 -0
- package/lib/utils/image_plugins/type_guards.js +21 -0
- package/lib/utils/markdown.js +4 -1
- package/lib/utils/pdf.d.ts +8 -0
- package/lib/utils/pdf.js +75 -0
- package/lib/utils/preprocess.d.ts +58 -128
- package/lib/utils/preprocess.js +37 -37
- package/lib/utils/utils.d.ts +12 -0
- package/lib/utils/utils.js +34 -0
- package/package.json +13 -4
package/lib/cli/tool-cli.js
CHANGED
|
@@ -11,7 +11,8 @@ import { getUrlsIfNeeded, selectTemplate } from "../utils/inquirer.js";
|
|
|
11
11
|
const main = async () => {
|
|
12
12
|
const { o: outdir, b: basedir, action, v: verbose, i: interactive, s: filename, cache } = args;
|
|
13
13
|
let { t: template } = args;
|
|
14
|
-
|
|
14
|
+
const { u: urls } = args;
|
|
15
|
+
const { llm_model, llm_agent } = args;
|
|
15
16
|
const baseDirPath = getBaseDirPath(basedir);
|
|
16
17
|
const outDirPath = getFullPath(baseDirPath, outdir ?? outDirName);
|
|
17
18
|
const cacheDirPath = getFullPath(outDirPath, cache ?? cacheDirName);
|
|
@@ -38,12 +39,13 @@ const main = async () => {
|
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
if (action === "scripting") {
|
|
42
|
+
const context = { outDirPath, templateName: template, urls, filename, cacheDirPath, llm_model, llm_agent };
|
|
41
43
|
if (interactive) {
|
|
42
|
-
await createMulmoScriptInteractively(
|
|
44
|
+
await createMulmoScriptInteractively(context);
|
|
43
45
|
}
|
|
44
46
|
else {
|
|
45
|
-
urls = await getUrlsIfNeeded(urls);
|
|
46
|
-
await createMulmoScriptFromUrl(
|
|
47
|
+
context.urls = await getUrlsIfNeeded(urls);
|
|
48
|
+
await createMulmoScriptFromUrl(context);
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
51
|
else if (action === "prompt") {
|
package/lib/methods/index.d.ts
CHANGED
package/lib/methods/index.js
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import { getFullPath } from "../utils/file.js";
|
|
3
|
+
export const MulmoMediaSourceMethods = {
|
|
4
|
+
async getText(mediaSource, context) {
|
|
5
|
+
if (mediaSource.kind === "text") {
|
|
6
|
+
return mediaSource.text;
|
|
7
|
+
}
|
|
8
|
+
if (mediaSource.kind === "url") {
|
|
9
|
+
const res = await fetch(mediaSource.url);
|
|
10
|
+
if (!res.ok) {
|
|
11
|
+
throw new Error(`Failed to fetch media source: ${mediaSource.url}`);
|
|
12
|
+
}
|
|
13
|
+
return await res.text();
|
|
14
|
+
}
|
|
15
|
+
if (mediaSource.kind === "path") {
|
|
16
|
+
const path = getFullPath(context.fileDirs.mulmoFileDirPath, mediaSource.path);
|
|
17
|
+
return fs.readFileSync(path, "utf-8");
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
},
|
|
21
|
+
};
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import "dotenv/config";
|
|
2
|
-
import { MulmoCanvasDimension, MulmoScript, MulmoBeat, SpeechOptions,
|
|
3
|
-
export type Text2ImageAgentInfo = {
|
|
4
|
-
provider: Text2ImageProvider;
|
|
5
|
-
agent: string;
|
|
6
|
-
imageParams: MulmoImageParams;
|
|
7
|
-
};
|
|
2
|
+
import { MulmoCanvasDimension, MulmoScript, MulmoBeat, SpeechOptions, Text2SpeechProvider, Text2ImageAgentInfo, BeatMediaType } from "../types/index.js";
|
|
8
3
|
export declare const MulmoScriptMethods: {
|
|
9
4
|
getPadding(script: MulmoScript): number;
|
|
10
5
|
getCanvasSize(script: MulmoScript): MulmoCanvasDimension;
|
|
@@ -13,4 +8,5 @@ export declare const MulmoScriptMethods: {
|
|
|
13
8
|
getTextSlideStyle(script: MulmoScript, beat: MulmoBeat): string;
|
|
14
9
|
getSpeechOptions(script: MulmoScript, beat: MulmoBeat): SpeechOptions | undefined;
|
|
15
10
|
getImageAgentInfo(script: MulmoScript): Text2ImageAgentInfo;
|
|
11
|
+
getImageType(_: MulmoScript, beat: MulmoBeat): BeatMediaType;
|
|
16
12
|
};
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import "dotenv/config";
|
|
2
2
|
import { text2ImageProviderSchema, text2SpeechProviderSchema, mulmoCanvasDimensionSchema } from "../types/schema.js";
|
|
3
3
|
const defaultTextSlideStyles = [
|
|
4
|
-
|
|
5
|
-
"
|
|
4
|
+
'*,*::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}}',
|
|
5
|
+
"body { margin: 60px; margin-top: 40px; color:#333; font-size: 30px; font-family: Arial, sans-serif; box-sizing: border-box; height: 100vh }",
|
|
6
|
+
"h1 { font-size: 56px; margin-bottom: 20px; text-align: center; }",
|
|
7
|
+
"h2 { font-size: 48px }",
|
|
8
|
+
"h3 { font-size: 36px }",
|
|
6
9
|
"ul { margin-left: 40px } ",
|
|
7
|
-
"pre {
|
|
10
|
+
"pre { background: #eeeecc; font-size: 16px; padding:4px }",
|
|
8
11
|
"p { margin-left: 40px }",
|
|
9
|
-
"table { font-size:
|
|
12
|
+
"table { font-size: 36px; margin: auto; border: 1px solid gray; border-collapse: collapse }",
|
|
10
13
|
"th { border-bottom: 1px solid gray }",
|
|
11
14
|
"td, th { padding: 8px }",
|
|
12
15
|
"tr:nth-child(even) { background-color: #eee }",
|
|
@@ -30,7 +33,8 @@ export const MulmoScriptMethods = {
|
|
|
30
33
|
const styles = script.textSlideParams?.cssStyles ?? defaultTextSlideStyles;
|
|
31
34
|
// NOTES: Taking advantage of CSS override rule (you can redefine it to override)
|
|
32
35
|
const extraStyles = beat.textSlideParams?.cssStyles ?? [];
|
|
33
|
-
|
|
36
|
+
// This code allows us to support both string and array of strings for cssStyles
|
|
37
|
+
return [...[styles], ...[extraStyles]].flat().join("\n");
|
|
34
38
|
},
|
|
35
39
|
getSpeechOptions(script, beat) {
|
|
36
40
|
return { ...script.speechParams.speakers[beat.speaker].speechOptions, ...beat.speechOptions };
|
|
@@ -48,4 +52,7 @@ export const MulmoScriptMethods = {
|
|
|
48
52
|
imageParams: { ...defaultImageParams, ...script.imageParams },
|
|
49
53
|
};
|
|
50
54
|
},
|
|
55
|
+
getImageType(_, beat) {
|
|
56
|
+
return beat.image?.type == "movie" ? "movie" : "image";
|
|
57
|
+
},
|
|
51
58
|
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import "dotenv/config";
|
|
2
2
|
import { ScriptingParams } from "../types/index.js";
|
|
3
|
-
export declare const createMulmoScriptInteractively: ({ outDirPath, cacheDirPath, filename, templateName, urls }: ScriptingParams) => Promise<void>;
|
|
3
|
+
export declare const createMulmoScriptInteractively: ({ outDirPath, cacheDirPath, filename, templateName, urls, llm_agent, llm_model }: ScriptingParams) => Promise<void>;
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import "dotenv/config";
|
|
2
2
|
import { GraphAILogger, GraphAI } from "graphai";
|
|
3
3
|
import { textInputAgent } from "@graphai/input_agents";
|
|
4
|
+
import { streamAgentFilterGenerator } from "@graphai/agent_filters";
|
|
4
5
|
import { openAIAgent } from "@graphai/openai_agent";
|
|
6
|
+
import { anthropicAgent } from "@graphai/anthropic_agent";
|
|
7
|
+
import { geminiAgent } from "@graphai/gemini_agent";
|
|
8
|
+
import { groqAgent } from "@graphai/groq_agent";
|
|
5
9
|
import * as agents from "@graphai/vanilla";
|
|
6
10
|
import { fileWriteAgent } from "@graphai/vanilla_node_agents";
|
|
7
11
|
import { readTemplatePrompt, mkdir } from "../utils/file.js";
|
|
8
12
|
import { browserlessCacheGenerator } from "../utils/filters.js";
|
|
9
13
|
import { browserlessAgent } from "@graphai/browserless_agent";
|
|
10
14
|
import validateMulmoScriptAgent from "../agents/validate_mulmo_script_agent.js";
|
|
11
|
-
import {
|
|
15
|
+
import { llmPair } from "../utils/utils.js";
|
|
16
|
+
// import { cliLoadingPlugin } from "../utils/plugins.js";
|
|
12
17
|
const { default: __, ...vanillaAgents } = agents;
|
|
13
18
|
const agentHeader = "\x1b[34m● \x1b[0m\x1b[1mAgent\x1b[0m:\x1b[0m";
|
|
14
19
|
const graphDataForScraping = {
|
|
@@ -65,6 +70,15 @@ const graphData = {
|
|
|
65
70
|
while: ":continue",
|
|
66
71
|
},
|
|
67
72
|
nodes: {
|
|
73
|
+
llmAgent: {
|
|
74
|
+
update: ":llmAgent",
|
|
75
|
+
},
|
|
76
|
+
llmModel: {
|
|
77
|
+
update: ":llmModel",
|
|
78
|
+
},
|
|
79
|
+
maxTokens: {
|
|
80
|
+
update: ":maxTokens",
|
|
81
|
+
},
|
|
68
82
|
fileName: {
|
|
69
83
|
update: ":fileName",
|
|
70
84
|
},
|
|
@@ -73,7 +87,7 @@ const graphData = {
|
|
|
73
87
|
},
|
|
74
88
|
messages: {
|
|
75
89
|
value: [],
|
|
76
|
-
update: ":reply.
|
|
90
|
+
update: ":reply.chatAgent.messages",
|
|
77
91
|
},
|
|
78
92
|
userInput: {
|
|
79
93
|
agent: "textInputAgent",
|
|
@@ -87,6 +101,9 @@ const graphData = {
|
|
|
87
101
|
inputs: {
|
|
88
102
|
messages: ":messages",
|
|
89
103
|
prompt: ":userInput.text",
|
|
104
|
+
llmAgent: ":llmAgent",
|
|
105
|
+
llmModel: ":llmModel",
|
|
106
|
+
maxTokens: ":maxTokens",
|
|
90
107
|
},
|
|
91
108
|
graph: {
|
|
92
109
|
loop: {
|
|
@@ -97,10 +114,12 @@ const graphData = {
|
|
|
97
114
|
value: 0,
|
|
98
115
|
update: ":counter.add(1)",
|
|
99
116
|
},
|
|
100
|
-
|
|
101
|
-
agent: "
|
|
117
|
+
chatAgent: {
|
|
118
|
+
agent: ":llmAgent",
|
|
102
119
|
params: {
|
|
103
|
-
model: "
|
|
120
|
+
model: ":llmModel",
|
|
121
|
+
stream: true,
|
|
122
|
+
max_tokens: ":maxTokens",
|
|
104
123
|
},
|
|
105
124
|
inputs: {
|
|
106
125
|
messages: ":messages",
|
|
@@ -111,7 +130,7 @@ const graphData = {
|
|
|
111
130
|
validateMulmoScriptAgent: {
|
|
112
131
|
agent: "validateMulmoScriptAgent",
|
|
113
132
|
inputs: {
|
|
114
|
-
text: ":
|
|
133
|
+
text: ":chatAgent.text.codeBlock()",
|
|
115
134
|
},
|
|
116
135
|
},
|
|
117
136
|
continue: {
|
|
@@ -120,11 +139,15 @@ const graphData = {
|
|
|
120
139
|
GraphAILogger.info("\n" + agentHeader + " \x1b[31mFailed to generate a valid script. Please try again.\n");
|
|
121
140
|
return false;
|
|
122
141
|
}
|
|
123
|
-
|
|
142
|
+
const result = !!codeBlock && !isValid;
|
|
143
|
+
if (result) {
|
|
144
|
+
GraphAILogger.info("\n" + agentHeader + " Generated script was broken. Retry generate a script.");
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
124
147
|
},
|
|
125
148
|
inputs: {
|
|
126
149
|
counter: ":counter",
|
|
127
|
-
codeBlock: ":
|
|
150
|
+
codeBlock: ":chatAgent.text.codeBlock()",
|
|
128
151
|
isValid: ":validateMulmoScriptAgent.isValid",
|
|
129
152
|
},
|
|
130
153
|
},
|
|
@@ -134,8 +157,8 @@ const graphData = {
|
|
|
134
157
|
json: {
|
|
135
158
|
agent: "copyAgent",
|
|
136
159
|
inputs: {
|
|
137
|
-
json: ":reply.
|
|
138
|
-
text: ":reply.
|
|
160
|
+
json: ":reply.chatAgent.text.codeBlock().jsonParse()",
|
|
161
|
+
text: ":reply.chatAgent.text.codeBlock()",
|
|
139
162
|
},
|
|
140
163
|
},
|
|
141
164
|
writeJSON: {
|
|
@@ -159,13 +182,6 @@ const graphData = {
|
|
|
159
182
|
array: [[":json.json", "==", undefined], "&&", [":userInput.text", "!=", "/bye"]],
|
|
160
183
|
},
|
|
161
184
|
},
|
|
162
|
-
agentResponse: {
|
|
163
|
-
if: ":shouldResponse.result",
|
|
164
|
-
agent: "consoleAgent",
|
|
165
|
-
inputs: {
|
|
166
|
-
text: "\n" + agentHeader + " ${:reply.llmAgent.text}\n",
|
|
167
|
-
},
|
|
168
|
-
},
|
|
169
185
|
checkInput: {
|
|
170
186
|
agent: "compareAgent",
|
|
171
187
|
inputs: { array: [":userInput.text", "!=", "/bye"] },
|
|
@@ -197,11 +213,23 @@ const scrapeWebContent = async (urls, cacheDirPath) => {
|
|
|
197
213
|
const prefixPrompt = "Here is the web content that can be used as reference material for the script:";
|
|
198
214
|
return `\n\n${prefixPrompt}\n${result?.sourceText.text}`;
|
|
199
215
|
};
|
|
200
|
-
export const createMulmoScriptInteractively = async ({ outDirPath, cacheDirPath, filename, templateName, urls }) => {
|
|
216
|
+
export const createMulmoScriptInteractively = async ({ outDirPath, cacheDirPath, filename, templateName, urls, llm_agent, llm_model }) => {
|
|
201
217
|
mkdir(outDirPath);
|
|
202
218
|
// if urls is not empty, scrape web content and reference it in the prompt
|
|
203
219
|
const webContentPrompt = urls.length > 0 ? await scrapeWebContent(urls, cacheDirPath) : "";
|
|
204
|
-
const
|
|
220
|
+
const { agent, model, max_tokens } = llmPair(llm_agent, llm_model);
|
|
221
|
+
GraphAILogger.log({ agent, model, max_tokens });
|
|
222
|
+
const streamAgentFilter = streamAgentFilterGenerator((context, data) => {
|
|
223
|
+
process.stdout.write(String(data));
|
|
224
|
+
});
|
|
225
|
+
const agentFilters = [
|
|
226
|
+
{
|
|
227
|
+
name: "streamAgentFilter",
|
|
228
|
+
agent: streamAgentFilter,
|
|
229
|
+
nodeIds: ["chatAgent"],
|
|
230
|
+
},
|
|
231
|
+
];
|
|
232
|
+
const graph = new GraphAI(graphData, { ...vanillaAgents, anthropicAgent, geminiAgent, groqAgent, openAIAgent, textInputAgent, fileWriteAgent, validateMulmoScriptAgent }, { agentFilters });
|
|
205
233
|
const prompt = readTemplatePrompt(templateName);
|
|
206
234
|
graph.injectValue("messages", [
|
|
207
235
|
{
|
|
@@ -211,7 +239,20 @@ export const createMulmoScriptInteractively = async ({ outDirPath, cacheDirPath,
|
|
|
211
239
|
]);
|
|
212
240
|
graph.injectValue("outdir", outDirPath);
|
|
213
241
|
graph.injectValue("fileName", filename);
|
|
214
|
-
graph.
|
|
242
|
+
graph.injectValue("llmAgent", agent);
|
|
243
|
+
graph.injectValue("llmModel", model);
|
|
244
|
+
graph.injectValue("maxTokens", max_tokens);
|
|
245
|
+
graph.registerCallback(({ nodeId, state }) => {
|
|
246
|
+
if (nodeId === "chatAgent") {
|
|
247
|
+
if (state === "executing") {
|
|
248
|
+
process.stdout.write(String("\n" + agentHeader + " "));
|
|
249
|
+
}
|
|
250
|
+
if (state === "completed") {
|
|
251
|
+
process.stdout.write("\n\n");
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
// graph.registerCallback(cliLoadingPlugin({ nodeId: "reply", message: "Loading..." }));
|
|
215
256
|
GraphAILogger.info(`${agentHeader} Hi! What topic would you like me to generate about?\n`);
|
|
216
257
|
await graph.run();
|
|
217
258
|
};
|
package/lib/types/index.d.ts
CHANGED
package/lib/types/index.js
CHANGED