mulmocast 0.0.5 → 0.0.7
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 +294 -39
- package/assets/audio/silent60sec.mp3 +0 -0
- package/assets/html/caption.html +45 -0
- package/assets/html/chart.html +1 -1
- package/assets/html/mermaid.html +6 -2
- package/assets/html/tailwind.html +13 -0
- package/assets/templates/business.json +2 -128
- package/assets/templates/children_book.json +1 -128
- package/assets/templates/coding.json +2 -136
- package/assets/templates/comic_strips.json +6 -0
- package/assets/templates/ghibli_strips.json +6 -0
- package/assets/templates/sensei_and_taro.json +1 -118
- package/lib/actions/audio.js +62 -39
- package/lib/actions/captions.d.ts +2 -0
- package/lib/actions/captions.js +75 -0
- package/lib/actions/images.js +34 -13
- package/lib/actions/index.d.ts +1 -0
- package/lib/actions/index.js +1 -0
- package/lib/actions/movie.js +102 -101
- package/lib/actions/pdf.js +26 -6
- package/lib/actions/translate.js +60 -39
- package/lib/agents/add_bgm_agent.js +15 -39
- package/lib/agents/combine_audio_files_agent.js +53 -35
- package/lib/agents/index.d.ts +2 -3
- package/lib/agents/index.js +2 -3
- package/lib/agents/tts_google_agent.d.ts +4 -0
- package/lib/agents/tts_google_agent.js +51 -0
- package/lib/agents/validate_schema_agent.d.ts +19 -0
- package/lib/agents/validate_schema_agent.js +36 -0
- package/lib/cli/args.d.ts +2 -0
- package/lib/cli/args.js +9 -2
- package/lib/cli/bin.d.ts +3 -0
- package/lib/cli/bin.js +38 -0
- package/lib/cli/cli.js +34 -7
- package/lib/cli/commands/audio/builder.d.ts +14 -0
- package/lib/cli/commands/audio/builder.js +6 -0
- package/lib/cli/commands/audio/handler.d.ts +4 -0
- package/lib/cli/commands/audio/handler.js +7 -0
- package/lib/cli/commands/audio/index.d.ts +4 -0
- package/lib/cli/commands/audio/index.js +4 -0
- package/lib/cli/commands/image/builder.d.ts +14 -0
- package/lib/cli/commands/image/builder.js +6 -0
- package/lib/cli/commands/image/handler.d.ts +4 -0
- package/lib/cli/commands/image/handler.js +7 -0
- package/lib/cli/commands/image/index.d.ts +4 -0
- package/lib/cli/commands/image/index.js +4 -0
- package/lib/cli/commands/movie/builder.d.ts +18 -0
- package/lib/cli/commands/movie/builder.js +19 -0
- package/lib/cli/commands/movie/handler.d.ts +6 -0
- package/lib/cli/commands/movie/handler.js +12 -0
- package/lib/cli/commands/movie/index.d.ts +4 -0
- package/lib/cli/commands/movie/index.js +4 -0
- package/lib/cli/commands/pdf/builder.d.ts +18 -0
- package/lib/cli/commands/pdf/builder.js +19 -0
- package/lib/cli/commands/pdf/handler.d.ts +6 -0
- package/lib/cli/commands/pdf/handler.js +8 -0
- package/lib/cli/commands/pdf/index.d.ts +4 -0
- package/lib/cli/commands/pdf/index.js +4 -0
- package/lib/cli/commands/tool/index.d.ts +6 -0
- package/lib/cli/commands/tool/index.js +8 -0
- package/lib/cli/commands/tool/prompt/builder.d.ts +4 -0
- package/lib/cli/commands/tool/prompt/builder.js +11 -0
- package/lib/cli/commands/tool/prompt/handler.d.ts +4 -0
- package/lib/cli/commands/tool/prompt/handler.js +14 -0
- package/lib/cli/commands/tool/prompt/index.d.ts +4 -0
- package/lib/cli/commands/tool/prompt/index.js +4 -0
- package/lib/cli/commands/tool/schema/builder.d.ts +2 -0
- package/lib/cli/commands/tool/schema/builder.js +3 -0
- package/lib/cli/commands/tool/schema/handler.d.ts +2 -0
- package/lib/cli/commands/tool/schema/handler.js +12 -0
- package/lib/cli/commands/tool/schema/index.d.ts +4 -0
- package/lib/cli/commands/tool/schema/index.js +4 -0
- package/lib/cli/commands/tool/scripting/builder.d.ts +20 -0
- package/lib/cli/commands/tool/scripting/builder.js +63 -0
- package/lib/cli/commands/tool/scripting/handler.d.ts +13 -0
- package/lib/cli/commands/tool/scripting/handler.js +36 -0
- package/lib/cli/commands/tool/scripting/index.d.ts +4 -0
- package/lib/cli/commands/tool/scripting/index.js +4 -0
- package/lib/cli/commands/tool/story_to_script/builder.d.ts +20 -0
- package/lib/cli/commands/tool/story_to_script/builder.js +61 -0
- package/lib/cli/commands/tool/story_to_script/handler.d.ts +13 -0
- package/lib/cli/commands/tool/story_to_script/handler.js +36 -0
- package/lib/cli/commands/tool/story_to_script/index.d.ts +4 -0
- package/lib/cli/commands/tool/story_to_script/index.js +4 -0
- package/lib/cli/commands/translate/builder.d.ts +14 -0
- package/lib/cli/commands/translate/builder.js +5 -0
- package/lib/cli/commands/translate/handler.d.ts +4 -0
- package/lib/cli/commands/translate/handler.js +6 -0
- package/lib/cli/commands/translate/index.d.ts +4 -0
- package/lib/cli/commands/translate/index.js +4 -0
- package/lib/cli/common.d.ts +6 -2
- package/lib/cli/common.js +18 -7
- package/lib/cli/helpers.d.ts +38 -0
- package/lib/cli/helpers.js +115 -0
- package/lib/cli/tool-args.d.ts +1 -0
- package/lib/cli/tool-args.js +1 -1
- package/lib/cli/tool-cli.js +8 -0
- package/lib/methods/mulmo_script.d.ts +0 -1
- package/lib/methods/mulmo_script.js +4 -7
- package/lib/methods/mulmo_script_template.d.ts +2 -2
- package/lib/methods/mulmo_script_template.js +3 -13
- package/lib/methods/mulmo_studio.d.ts +8 -0
- package/lib/methods/mulmo_studio.js +24 -0
- package/lib/tools/create_mulmo_script_from_url.d.ts +1 -1
- package/lib/tools/create_mulmo_script_from_url.js +43 -14
- package/lib/tools/create_mulmo_script_interactively.d.ts +1 -1
- package/lib/tools/create_mulmo_script_interactively.js +21 -20
- package/lib/tools/dump_prompt.js +2 -0
- package/lib/tools/story_to_script.d.ts +12 -0
- package/lib/tools/story_to_script.js +275 -0
- package/lib/types/cli_types.d.ts +14 -0
- package/lib/types/cli_types.js +1 -0
- package/lib/types/schema.d.ts +637 -1766
- package/lib/types/schema.js +77 -8
- package/lib/types/type.d.ts +10 -3
- package/lib/utils/const.d.ts +5 -0
- package/lib/utils/const.js +5 -0
- package/lib/utils/ffmpeg_utils.d.ts +12 -0
- package/lib/utils/ffmpeg_utils.js +63 -0
- package/lib/utils/file.d.ts +8 -3
- package/lib/utils/file.js +40 -9
- package/lib/utils/filters.js +16 -11
- package/lib/utils/image_plugins/chart.js +6 -1
- package/lib/utils/image_plugins/html_tailwind.d.ts +3 -0
- package/lib/utils/image_plugins/html_tailwind.js +18 -0
- package/lib/utils/image_plugins/index.d.ts +2 -1
- package/lib/utils/image_plugins/index.js +2 -1
- package/lib/utils/image_plugins/mermaid.js +1 -1
- package/lib/utils/image_plugins/tailwind.d.ts +3 -0
- package/lib/utils/image_plugins/tailwind.js +18 -0
- package/lib/utils/image_plugins/text_slide.js +9 -2
- package/lib/utils/markdown.d.ts +1 -1
- package/lib/utils/markdown.js +8 -4
- package/lib/utils/preprocess.d.ts +40 -10
- package/lib/utils/preprocess.js +7 -2
- package/lib/utils/prompt.d.ts +16 -0
- package/lib/utils/prompt.js +74 -0
- package/lib/utils/utils.d.ts +10 -5
- package/lib/utils/utils.js +37 -17
- package/package.json +27 -23
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import "dotenv/config";
|
|
2
2
|
import { GraphAI } from "graphai";
|
|
3
3
|
import { openAIAgent } from "@graphai/openai_agent";
|
|
4
|
+
import { anthropicAgent } from "@graphai/anthropic_agent";
|
|
5
|
+
import { geminiAgent } from "@graphai/gemini_agent";
|
|
6
|
+
import { groqAgent } from "@graphai/groq_agent";
|
|
4
7
|
import * as agents from "@graphai/vanilla";
|
|
5
8
|
import { fileWriteAgent } from "@graphai/vanilla_node_agents";
|
|
6
9
|
import { browserlessAgent } from "@graphai/browserless_agent";
|
|
7
|
-
import
|
|
10
|
+
import validateSchemaAgent from "../agents/validate_schema_agent.js";
|
|
8
11
|
import { readTemplatePrompt, mkdir, writingMessage } from "../utils/file.js";
|
|
9
12
|
import { browserlessCacheGenerator } from "../utils/filters.js";
|
|
10
|
-
import { urlsSchema } from "../types/schema.js";
|
|
13
|
+
import { mulmoScriptSchema, urlsSchema } from "../types/schema.js";
|
|
11
14
|
import { cliLoadingPlugin } from "../utils/plugins.js";
|
|
15
|
+
import { graphDataScriptFromUrlPrompt } from "../utils/prompt.js";
|
|
16
|
+
import { llmPair } from "../utils/utils.js";
|
|
12
17
|
const { default: __, ...vanillaAgents } = agents;
|
|
13
18
|
const graphData = {
|
|
14
19
|
version: 0.5,
|
|
@@ -27,6 +32,15 @@ const graphData = {
|
|
|
27
32
|
fileName: {
|
|
28
33
|
value: "",
|
|
29
34
|
},
|
|
35
|
+
llmAgent: {
|
|
36
|
+
value: "",
|
|
37
|
+
},
|
|
38
|
+
llmModel: {
|
|
39
|
+
value: "",
|
|
40
|
+
},
|
|
41
|
+
maxTokens: {
|
|
42
|
+
value: 0,
|
|
43
|
+
},
|
|
30
44
|
// get the text content of the urls
|
|
31
45
|
fetchResults: {
|
|
32
46
|
agent: "mapAgent",
|
|
@@ -74,6 +88,9 @@ const graphData = {
|
|
|
74
88
|
inputs: {
|
|
75
89
|
sourceText: ":sourceText",
|
|
76
90
|
prompt: ":prompt",
|
|
91
|
+
llmAgent: ":llmAgent",
|
|
92
|
+
llmModel: ":llmModel",
|
|
93
|
+
maxTokens: ":maxTokens",
|
|
77
94
|
},
|
|
78
95
|
graph: {
|
|
79
96
|
loop: {
|
|
@@ -85,18 +102,23 @@ const graphData = {
|
|
|
85
102
|
value: 0,
|
|
86
103
|
update: ":counter.add(1)",
|
|
87
104
|
},
|
|
88
|
-
|
|
89
|
-
agent: "
|
|
105
|
+
llm: {
|
|
106
|
+
agent: ":llmAgent",
|
|
90
107
|
inputs: {
|
|
91
|
-
model: "gpt-4o",
|
|
92
108
|
system: ":prompt",
|
|
93
|
-
prompt: "
|
|
109
|
+
prompt: graphDataScriptFromUrlPrompt("${:sourceText.text}"),
|
|
110
|
+
params: {
|
|
111
|
+
model: ":llmModel",
|
|
112
|
+
system: ":prompt",
|
|
113
|
+
max_tokens: ":maxTokens",
|
|
114
|
+
},
|
|
94
115
|
},
|
|
95
116
|
},
|
|
96
|
-
|
|
97
|
-
agent: "
|
|
117
|
+
validateSchemaAgent: {
|
|
118
|
+
agent: "validateSchemaAgent",
|
|
98
119
|
inputs: {
|
|
99
|
-
text: ":
|
|
120
|
+
text: ":llm.text.codeBlock()",
|
|
121
|
+
schema: mulmoScriptSchema,
|
|
100
122
|
},
|
|
101
123
|
isResult: true,
|
|
102
124
|
},
|
|
@@ -105,7 +127,7 @@ const graphData = {
|
|
|
105
127
|
return !isValid && counter < 3;
|
|
106
128
|
},
|
|
107
129
|
inputs: {
|
|
108
|
-
isValid: ":
|
|
130
|
+
isValid: ":validateSchemaAgent.isValid",
|
|
109
131
|
counter: ":counter",
|
|
110
132
|
},
|
|
111
133
|
},
|
|
@@ -113,17 +135,17 @@ const graphData = {
|
|
|
113
135
|
},
|
|
114
136
|
},
|
|
115
137
|
writeJSON: {
|
|
116
|
-
if: ":mulmoScript.
|
|
138
|
+
if: ":mulmoScript.validateSchemaAgent.isValid",
|
|
117
139
|
agent: "fileWriteAgent",
|
|
118
140
|
inputs: {
|
|
119
141
|
file: "${:outdir}/${:fileName}-${@now}.json",
|
|
120
|
-
text: ":mulmoScript.
|
|
142
|
+
text: ":mulmoScript.validateSchemaAgent.data.toJSON()",
|
|
121
143
|
},
|
|
122
144
|
isResult: true,
|
|
123
145
|
},
|
|
124
146
|
},
|
|
125
147
|
};
|
|
126
|
-
export const createMulmoScriptFromUrl = async ({ urls, templateName, outDirPath, filename, cacheDirPath }) => {
|
|
148
|
+
export const createMulmoScriptFromUrl = async ({ urls, templateName, outDirPath, filename, cacheDirPath, llm, llm_model }) => {
|
|
127
149
|
mkdir(outDirPath);
|
|
128
150
|
mkdir(cacheDirPath);
|
|
129
151
|
const parsedUrls = urlsSchema.parse(urls);
|
|
@@ -135,17 +157,24 @@ export const createMulmoScriptFromUrl = async ({ urls, templateName, outDirPath,
|
|
|
135
157
|
nodeIds: ["fetcher"],
|
|
136
158
|
},
|
|
137
159
|
];
|
|
160
|
+
const { agent, model, max_tokens } = llmPair(llm, llm_model);
|
|
138
161
|
const graph = new GraphAI(graphData, {
|
|
139
162
|
...vanillaAgents,
|
|
140
163
|
openAIAgent,
|
|
164
|
+
anthropicAgent,
|
|
165
|
+
geminiAgent,
|
|
166
|
+
groqAgent,
|
|
141
167
|
browserlessAgent,
|
|
142
|
-
|
|
168
|
+
validateSchemaAgent,
|
|
143
169
|
fileWriteAgent,
|
|
144
170
|
}, { agentFilters });
|
|
145
171
|
graph.injectValue("urls", parsedUrls);
|
|
146
172
|
graph.injectValue("prompt", readTemplatePrompt(templateName));
|
|
147
173
|
graph.injectValue("outdir", outDirPath);
|
|
148
174
|
graph.injectValue("fileName", filename);
|
|
175
|
+
graph.injectValue("llmAgent", agent);
|
|
176
|
+
graph.injectValue("llmModel", model);
|
|
177
|
+
graph.injectValue("maxTokens", max_tokens);
|
|
149
178
|
graph.registerCallback(cliLoadingPlugin({ nodeId: "mulmoScript", message: "Generating script..." }));
|
|
150
179
|
const result = await graph.run();
|
|
151
180
|
writingMessage(result?.writeJSON?.path ?? "");
|
|
@@ -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,
|
|
3
|
+
export declare const createMulmoScriptInteractively: ({ outDirPath, cacheDirPath, filename, templateName, urls, llm, llm_model }: ScriptingParams) => Promise<void>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "dotenv/config";
|
|
2
2
|
import { GraphAILogger, GraphAI } from "graphai";
|
|
3
3
|
import { textInputAgent } from "@graphai/input_agents";
|
|
4
|
-
import {
|
|
4
|
+
import { consoleStreamDataAgentFilter } from "@graphai/stream_agent_filter/node";
|
|
5
5
|
import { openAIAgent } from "@graphai/openai_agent";
|
|
6
6
|
import { anthropicAgent } from "@graphai/anthropic_agent";
|
|
7
7
|
import { geminiAgent } from "@graphai/gemini_agent";
|
|
@@ -10,9 +10,11 @@ import * as agents from "@graphai/vanilla";
|
|
|
10
10
|
import { fileWriteAgent } from "@graphai/vanilla_node_agents";
|
|
11
11
|
import { readTemplatePrompt, mkdir } from "../utils/file.js";
|
|
12
12
|
import { browserlessCacheGenerator } from "../utils/filters.js";
|
|
13
|
+
import { mulmoScriptSchema } from "../types/index.js";
|
|
13
14
|
import { browserlessAgent } from "@graphai/browserless_agent";
|
|
14
|
-
import
|
|
15
|
+
import validateSchemaAgent from "../agents/validate_schema_agent.js";
|
|
15
16
|
import { llmPair } from "../utils/utils.js";
|
|
17
|
+
import { interactiveClarificationPrompt, prefixPrompt } from "../utils/prompt.js";
|
|
16
18
|
// import { cliLoadingPlugin } from "../utils/plugins.js";
|
|
17
19
|
const { default: __, ...vanillaAgents } = agents;
|
|
18
20
|
const agentHeader = "\x1b[34m● \x1b[0m\x1b[1mAgent\x1b[0m:\x1b[0m";
|
|
@@ -116,21 +118,25 @@ const graphData = {
|
|
|
116
118
|
},
|
|
117
119
|
chatAgent: {
|
|
118
120
|
agent: ":llmAgent",
|
|
119
|
-
params: {
|
|
120
|
-
model: ":llmModel",
|
|
121
|
-
stream: true,
|
|
122
|
-
max_tokens: ":maxTokens",
|
|
123
|
-
},
|
|
124
121
|
inputs: {
|
|
125
122
|
messages: ":messages",
|
|
126
123
|
prompt: ":prompt",
|
|
124
|
+
params: {
|
|
125
|
+
model: ":llmModel",
|
|
126
|
+
stream: true,
|
|
127
|
+
dataStream: true,
|
|
128
|
+
max_tokens: ":maxTokens",
|
|
129
|
+
},
|
|
127
130
|
},
|
|
128
131
|
isResult: true,
|
|
129
132
|
},
|
|
130
|
-
|
|
131
|
-
|
|
133
|
+
validateSchemaAgent: {
|
|
134
|
+
if: ":chatAgent.text.codeBlock()",
|
|
135
|
+
defaultValue: false,
|
|
136
|
+
agent: "validateSchemaAgent",
|
|
132
137
|
inputs: {
|
|
133
138
|
text: ":chatAgent.text.codeBlock()",
|
|
139
|
+
schema: mulmoScriptSchema,
|
|
134
140
|
},
|
|
135
141
|
},
|
|
136
142
|
continue: {
|
|
@@ -148,7 +154,7 @@ const graphData = {
|
|
|
148
154
|
inputs: {
|
|
149
155
|
counter: ":counter",
|
|
150
156
|
codeBlock: ":chatAgent.text.codeBlock()",
|
|
151
|
-
isValid: ":
|
|
157
|
+
isValid: ":validateSchemaAgent.isValid",
|
|
152
158
|
},
|
|
153
159
|
},
|
|
154
160
|
},
|
|
@@ -192,7 +198,6 @@ const graphData = {
|
|
|
192
198
|
},
|
|
193
199
|
},
|
|
194
200
|
};
|
|
195
|
-
const interactiveClarificationPrompt = `If there are any unclear points, be sure to ask the user questions and clarify them before generating the script.`;
|
|
196
201
|
const scrapeWebContent = async (urls, cacheDirPath) => {
|
|
197
202
|
mkdir(cacheDirPath);
|
|
198
203
|
GraphAILogger.info(`${agentHeader} Scraping ${urls.length} URLs...\n`);
|
|
@@ -210,26 +215,22 @@ const scrapeWebContent = async (urls, cacheDirPath) => {
|
|
|
210
215
|
if (!result?.sourceText?.text) {
|
|
211
216
|
return "";
|
|
212
217
|
}
|
|
213
|
-
const prefixPrompt = "Here is the web content that can be used as reference material for the script:";
|
|
214
218
|
return `\n\n${prefixPrompt}\n${result?.sourceText.text}`;
|
|
215
219
|
};
|
|
216
|
-
export const createMulmoScriptInteractively = async ({ outDirPath, cacheDirPath, filename, templateName, urls,
|
|
220
|
+
export const createMulmoScriptInteractively = async ({ outDirPath, cacheDirPath, filename, templateName, urls, llm, llm_model }) => {
|
|
217
221
|
mkdir(outDirPath);
|
|
218
222
|
// if urls is not empty, scrape web content and reference it in the prompt
|
|
219
223
|
const webContentPrompt = urls.length > 0 ? await scrapeWebContent(urls, cacheDirPath) : "";
|
|
220
|
-
const { agent, model, max_tokens } = llmPair(
|
|
224
|
+
const { agent, model, max_tokens } = llmPair(llm, llm_model);
|
|
221
225
|
GraphAILogger.log({ agent, model, max_tokens });
|
|
222
|
-
const streamAgentFilter = streamAgentFilterGenerator((context, data) => {
|
|
223
|
-
process.stdout.write(String(data));
|
|
224
|
-
});
|
|
225
226
|
const agentFilters = [
|
|
226
227
|
{
|
|
227
|
-
name: "
|
|
228
|
-
agent:
|
|
228
|
+
name: "consoleStreamDataAgentFilter",
|
|
229
|
+
agent: consoleStreamDataAgentFilter,
|
|
229
230
|
nodeIds: ["chatAgent"],
|
|
230
231
|
},
|
|
231
232
|
];
|
|
232
|
-
const graph = new GraphAI(graphData, { ...vanillaAgents, anthropicAgent, geminiAgent, groqAgent, openAIAgent, textInputAgent, fileWriteAgent,
|
|
233
|
+
const graph = new GraphAI(graphData, { ...vanillaAgents, anthropicAgent, geminiAgent, groqAgent, openAIAgent, textInputAgent, fileWriteAgent, validateSchemaAgent }, { agentFilters });
|
|
233
234
|
const prompt = readTemplatePrompt(templateName);
|
|
234
235
|
graph.injectValue("messages", [
|
|
235
236
|
{
|
package/lib/tools/dump_prompt.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { GraphAILogger } from "graphai";
|
|
2
2
|
import { readTemplatePrompt } from "../utils/file.js";
|
|
3
|
+
import clipboardy from "clipboardy";
|
|
3
4
|
export const dumpPromptFromTemplate = async ({ templateName }) => {
|
|
4
5
|
const prompt = readTemplatePrompt(templateName);
|
|
5
6
|
GraphAILogger.info(prompt);
|
|
7
|
+
clipboardy.write(prompt);
|
|
6
8
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { MulmoStoryboard, StoryToScriptGenerateMode } from "../types/index.js";
|
|
2
|
+
import { LLM } from "../utils/utils.js";
|
|
3
|
+
export declare const storyToScript: ({ story, beatsPerScene, templateName, outdir, fileName, llm, llmModel, generateMode, }: {
|
|
4
|
+
story: MulmoStoryboard;
|
|
5
|
+
beatsPerScene: number;
|
|
6
|
+
templateName: string;
|
|
7
|
+
outdir: string;
|
|
8
|
+
fileName: string;
|
|
9
|
+
llm?: LLM;
|
|
10
|
+
llmModel?: string;
|
|
11
|
+
generateMode: StoryToScriptGenerateMode;
|
|
12
|
+
}) => Promise<void>;
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { getTemplateFilePath, readAndParseJson, readScriptTemplateFile, writingMessage } from "../utils/file.js";
|
|
2
|
+
import { mulmoScriptSchema, mulmoScriptTemplateSchema } from "../types/schema.js";
|
|
3
|
+
import { GraphAI, GraphAILogger } from "graphai";
|
|
4
|
+
import { openAIAgent } from "@graphai/openai_agent";
|
|
5
|
+
import { anthropicAgent } from "@graphai/anthropic_agent";
|
|
6
|
+
import { geminiAgent } from "@graphai/gemini_agent";
|
|
7
|
+
import { groqAgent } from "@graphai/groq_agent";
|
|
8
|
+
import * as agents from "@graphai/vanilla";
|
|
9
|
+
import { graphDataScriptGeneratePrompt, sceneToBeatsPrompt, storyToScriptInfoPrompt, storyToScriptPrompt } from "../utils/prompt.js";
|
|
10
|
+
import { fileWriteAgent } from "@graphai/vanilla_node_agents";
|
|
11
|
+
import validateSchemaAgent from "../agents/validate_schema_agent.js";
|
|
12
|
+
import { llmPair } from "../utils/utils.js";
|
|
13
|
+
import { storyToScriptGenerateMode } from "../utils/const.js";
|
|
14
|
+
import { cliLoadingPlugin } from "../utils/plugins.js";
|
|
15
|
+
const { default: __, ...vanillaAgents } = agents;
|
|
16
|
+
const createValidatedScriptGraphData = ({ systemPrompt, prompt, schema, llmAgent, llmModel, maxTokens, }) => {
|
|
17
|
+
return {
|
|
18
|
+
loop: {
|
|
19
|
+
while: ":continue",
|
|
20
|
+
},
|
|
21
|
+
nodes: {
|
|
22
|
+
counter: {
|
|
23
|
+
value: 0,
|
|
24
|
+
update: ":counter.add(1)",
|
|
25
|
+
},
|
|
26
|
+
llm: {
|
|
27
|
+
agent: llmAgent,
|
|
28
|
+
inputs: {
|
|
29
|
+
model: llmModel,
|
|
30
|
+
system: systemPrompt,
|
|
31
|
+
prompt: prompt,
|
|
32
|
+
max_tokens: maxTokens,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
validateSchema: {
|
|
36
|
+
agent: "validateSchemaAgent",
|
|
37
|
+
inputs: {
|
|
38
|
+
text: ":llm.text.codeBlock()",
|
|
39
|
+
schema: schema,
|
|
40
|
+
},
|
|
41
|
+
isResult: true,
|
|
42
|
+
},
|
|
43
|
+
continue: {
|
|
44
|
+
agent: ({ isValid, counter }) => {
|
|
45
|
+
if (counter >= 3) {
|
|
46
|
+
GraphAILogger.info("Failed to generate a valid script. Please try again.");
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
return !isValid;
|
|
50
|
+
},
|
|
51
|
+
inputs: {
|
|
52
|
+
counter: ":counter",
|
|
53
|
+
isValid: ":validateSchema.isValid",
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
const stepWiseGraphData = {
|
|
60
|
+
version: 0.5,
|
|
61
|
+
nodes: {
|
|
62
|
+
scenes: {
|
|
63
|
+
value: [],
|
|
64
|
+
},
|
|
65
|
+
beatsPrompt: {
|
|
66
|
+
value: "",
|
|
67
|
+
},
|
|
68
|
+
scriptInfoPrompt: {
|
|
69
|
+
value: "",
|
|
70
|
+
},
|
|
71
|
+
outdir: {
|
|
72
|
+
value: "",
|
|
73
|
+
},
|
|
74
|
+
fileName: {
|
|
75
|
+
value: "",
|
|
76
|
+
},
|
|
77
|
+
llmAgent: {
|
|
78
|
+
value: "",
|
|
79
|
+
},
|
|
80
|
+
llmModel: {
|
|
81
|
+
value: "",
|
|
82
|
+
},
|
|
83
|
+
maxTokens: {
|
|
84
|
+
value: 0,
|
|
85
|
+
},
|
|
86
|
+
script: {
|
|
87
|
+
agent: "mapAgent",
|
|
88
|
+
inputs: {
|
|
89
|
+
rows: ":scenes",
|
|
90
|
+
prompt: ":beatsPrompt",
|
|
91
|
+
llmAgent: ":llmAgent",
|
|
92
|
+
llmModel: ":llmModel",
|
|
93
|
+
maxTokens: ":maxTokens",
|
|
94
|
+
},
|
|
95
|
+
params: {
|
|
96
|
+
compositeResult: true,
|
|
97
|
+
},
|
|
98
|
+
graph: {
|
|
99
|
+
nodes: {
|
|
100
|
+
script: {
|
|
101
|
+
agent: "nestedAgent",
|
|
102
|
+
inputs: {
|
|
103
|
+
prompt: ":prompt",
|
|
104
|
+
row: ":row",
|
|
105
|
+
llmAgent: ":llmAgent",
|
|
106
|
+
llmModel: ":llmModel",
|
|
107
|
+
maxTokens: ":maxTokens",
|
|
108
|
+
},
|
|
109
|
+
graph: createValidatedScriptGraphData({
|
|
110
|
+
systemPrompt: ":prompt",
|
|
111
|
+
prompt: graphDataScriptGeneratePrompt("${:row}"),
|
|
112
|
+
schema: mulmoScriptSchema.shape.beats,
|
|
113
|
+
llmAgent: ":llmAgent",
|
|
114
|
+
llmModel: ":llmModel",
|
|
115
|
+
maxTokens: ":maxTokens",
|
|
116
|
+
}),
|
|
117
|
+
},
|
|
118
|
+
json: {
|
|
119
|
+
agent: "copyAgent",
|
|
120
|
+
inputs: {
|
|
121
|
+
json: ":script.validateSchema.data",
|
|
122
|
+
},
|
|
123
|
+
params: {
|
|
124
|
+
namedKey: "json",
|
|
125
|
+
},
|
|
126
|
+
isResult: true,
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
beats: {
|
|
132
|
+
agent: "arrayFlatAgent",
|
|
133
|
+
inputs: {
|
|
134
|
+
array: ":script.json",
|
|
135
|
+
},
|
|
136
|
+
isResult: true,
|
|
137
|
+
},
|
|
138
|
+
scriptInfo: {
|
|
139
|
+
agent: "nestedAgent",
|
|
140
|
+
inputs: {
|
|
141
|
+
prompt: ":scriptInfoPrompt",
|
|
142
|
+
llmAgent: ":llmAgent",
|
|
143
|
+
llmModel: ":llmModel",
|
|
144
|
+
maxTokens: ":maxTokens",
|
|
145
|
+
},
|
|
146
|
+
graph: createValidatedScriptGraphData({
|
|
147
|
+
systemPrompt: "",
|
|
148
|
+
prompt: ":prompt",
|
|
149
|
+
schema: mulmoScriptSchema.omit({ beats: true }),
|
|
150
|
+
llmAgent: ":llmAgent",
|
|
151
|
+
llmModel: ":llmModel",
|
|
152
|
+
maxTokens: ":maxTokens",
|
|
153
|
+
}),
|
|
154
|
+
},
|
|
155
|
+
mergedScript: {
|
|
156
|
+
agent: "mergeObjectAgent",
|
|
157
|
+
inputs: {
|
|
158
|
+
items: [":scriptInfo.validateSchema.data", { beats: ":beats.array" }],
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
writeJSON: {
|
|
162
|
+
agent: "fileWriteAgent",
|
|
163
|
+
inputs: {
|
|
164
|
+
file: "${:outdir}/${:fileName}-${@now}.json",
|
|
165
|
+
text: ":mergedScript.toJSON()",
|
|
166
|
+
},
|
|
167
|
+
isResult: true,
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
const oneStepGraphData = {
|
|
172
|
+
version: 0.5,
|
|
173
|
+
nodes: {
|
|
174
|
+
prompt: {
|
|
175
|
+
value: "",
|
|
176
|
+
},
|
|
177
|
+
outdir: {
|
|
178
|
+
value: "",
|
|
179
|
+
},
|
|
180
|
+
fileName: {
|
|
181
|
+
value: "",
|
|
182
|
+
},
|
|
183
|
+
llmAgent: {
|
|
184
|
+
value: "",
|
|
185
|
+
},
|
|
186
|
+
llmModel: {
|
|
187
|
+
value: "",
|
|
188
|
+
},
|
|
189
|
+
maxTokens: {
|
|
190
|
+
value: 0,
|
|
191
|
+
},
|
|
192
|
+
script: {
|
|
193
|
+
agent: "nestedAgent",
|
|
194
|
+
inputs: {
|
|
195
|
+
prompt: ":prompt",
|
|
196
|
+
llmAgent: ":llmAgent",
|
|
197
|
+
llmModel: ":llmModel",
|
|
198
|
+
maxTokens: ":maxTokens",
|
|
199
|
+
},
|
|
200
|
+
graph: createValidatedScriptGraphData({
|
|
201
|
+
systemPrompt: "",
|
|
202
|
+
prompt: graphDataScriptGeneratePrompt("${:prompt}"),
|
|
203
|
+
schema: mulmoScriptSchema,
|
|
204
|
+
llmAgent: ":llmAgent",
|
|
205
|
+
llmModel: ":llmModel",
|
|
206
|
+
maxTokens: ":maxTokens",
|
|
207
|
+
}),
|
|
208
|
+
},
|
|
209
|
+
json: {
|
|
210
|
+
agent: "copyAgent",
|
|
211
|
+
inputs: {
|
|
212
|
+
json: ":script.validateSchema.data",
|
|
213
|
+
},
|
|
214
|
+
params: {
|
|
215
|
+
namedKey: "json",
|
|
216
|
+
},
|
|
217
|
+
isResult: true,
|
|
218
|
+
},
|
|
219
|
+
writeJSON: {
|
|
220
|
+
agent: "fileWriteAgent",
|
|
221
|
+
inputs: {
|
|
222
|
+
file: "${:outdir}/${:fileName}-${@now}.json",
|
|
223
|
+
text: ":json.toJSON()",
|
|
224
|
+
},
|
|
225
|
+
isResult: true,
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
const generateBeatsPrompt = async (template, beatsPerScene, story) => {
|
|
230
|
+
const allScenes = story.scenes.map((scene) => scene.description).join("\n");
|
|
231
|
+
const sampleBeats = template.scriptName ? readScriptTemplateFile(template.scriptName).beats : [];
|
|
232
|
+
return sceneToBeatsPrompt({ sampleBeats, beatsPerScene, allScenes });
|
|
233
|
+
};
|
|
234
|
+
const generateScriptInfoPrompt = async (template, story) => {
|
|
235
|
+
if (!template.scriptName) {
|
|
236
|
+
// TODO: use default schema
|
|
237
|
+
throw new Error("script is not provided");
|
|
238
|
+
}
|
|
239
|
+
const script = readScriptTemplateFile(template.scriptName);
|
|
240
|
+
const { beats: __, ...scriptWithoutBeats } = script;
|
|
241
|
+
return storyToScriptInfoPrompt(scriptWithoutBeats, story);
|
|
242
|
+
};
|
|
243
|
+
const generateScriptPrompt = async (template, beatsPerScene, story) => {
|
|
244
|
+
if (!template.scriptName) {
|
|
245
|
+
// TODO: use default schema
|
|
246
|
+
throw new Error("script is not provided");
|
|
247
|
+
}
|
|
248
|
+
const script = readScriptTemplateFile(template.scriptName);
|
|
249
|
+
return storyToScriptPrompt(script, beatsPerScene, story);
|
|
250
|
+
};
|
|
251
|
+
export const storyToScript = async ({ story, beatsPerScene, templateName, outdir, fileName, llm, llmModel, generateMode, }) => {
|
|
252
|
+
const template = readAndParseJson(getTemplateFilePath(templateName), mulmoScriptTemplateSchema);
|
|
253
|
+
const { agent, model, max_tokens } = llmPair(llm, llmModel);
|
|
254
|
+
const beatsPrompt = await generateBeatsPrompt(template, beatsPerScene, story);
|
|
255
|
+
const scriptInfoPrompt = await generateScriptInfoPrompt(template, story);
|
|
256
|
+
const scriptPrompt = await generateScriptPrompt(template, beatsPerScene, story);
|
|
257
|
+
const graphData = generateMode === storyToScriptGenerateMode.stepWise ? stepWiseGraphData : oneStepGraphData;
|
|
258
|
+
const graph = new GraphAI(graphData, { ...vanillaAgents, openAIAgent, anthropicAgent, geminiAgent, groqAgent, fileWriteAgent, validateSchemaAgent });
|
|
259
|
+
if (generateMode === storyToScriptGenerateMode.stepWise) {
|
|
260
|
+
graph.injectValue("scenes", story.scenes);
|
|
261
|
+
graph.injectValue("beatsPrompt", beatsPrompt);
|
|
262
|
+
graph.injectValue("scriptInfoPrompt", scriptInfoPrompt);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
graph.injectValue("prompt", scriptPrompt);
|
|
266
|
+
}
|
|
267
|
+
graph.injectValue("outdir", outdir);
|
|
268
|
+
graph.injectValue("fileName", fileName);
|
|
269
|
+
graph.injectValue("llmAgent", agent);
|
|
270
|
+
graph.injectValue("llmModel", model);
|
|
271
|
+
graph.injectValue("maxTokens", max_tokens);
|
|
272
|
+
graph.registerCallback(cliLoadingPlugin({ nodeId: "script", message: "Generating script..." }));
|
|
273
|
+
const result = await graph.run();
|
|
274
|
+
writingMessage(result?.writeJSON?.path ?? "");
|
|
275
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Arguments } from "yargs";
|
|
2
|
+
export type ToolGlobalOptions = {
|
|
3
|
+
v?: boolean;
|
|
4
|
+
};
|
|
5
|
+
export type ToolCliArgs<T = object> = Arguments<T & ToolGlobalOptions>;
|
|
6
|
+
export type GlobalOptions = {
|
|
7
|
+
v?: boolean;
|
|
8
|
+
o?: string;
|
|
9
|
+
b?: string;
|
|
10
|
+
l?: string;
|
|
11
|
+
f?: boolean;
|
|
12
|
+
file?: string;
|
|
13
|
+
};
|
|
14
|
+
export type CliArgs<T = object> = Arguments<T & GlobalOptions>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|