mulmocast 0.0.1 → 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.
Files changed (115) hide show
  1. package/README.md +129 -15
  2. package/assets/font/NotoSansJP-Regular.ttf +0 -0
  3. package/assets/html/chart.html +38 -0
  4. package/assets/html/mermaid.html +51 -0
  5. package/assets/templates/business.json +57 -14
  6. package/assets/templates/children_book.json +1 -3
  7. package/assets/templates/coding.json +140 -0
  8. package/lib/actions/audio.d.ts +2 -2
  9. package/lib/actions/audio.js +88 -101
  10. package/lib/actions/images.d.ts +1 -1
  11. package/lib/actions/images.js +50 -88
  12. package/lib/actions/index.d.ts +5 -0
  13. package/lib/actions/index.js +5 -0
  14. package/lib/actions/movie.d.ts +9 -1
  15. package/lib/actions/movie.js +124 -65
  16. package/lib/actions/pdf.d.ts +2 -0
  17. package/lib/actions/pdf.js +211 -0
  18. package/lib/actions/pdf2.d.ts +2 -0
  19. package/lib/actions/pdf2.js +203 -0
  20. package/lib/actions/translate.d.ts +1 -1
  21. package/lib/actions/translate.js +38 -61
  22. package/lib/agents/add_bgm_agent.d.ts +1 -1
  23. package/lib/agents/add_bgm_agent.js +10 -14
  24. package/lib/agents/anthropic_agent.d.ts +23 -0
  25. package/lib/agents/anthropic_agent.js +162 -0
  26. package/lib/agents/combine_audio_files_agent.d.ts +1 -1
  27. package/lib/agents/combine_audio_files_agent.js +33 -32
  28. package/lib/agents/image_google_agent.d.ts +1 -1
  29. package/lib/agents/image_google_agent.js +8 -11
  30. package/lib/agents/image_openai_agent.js +7 -14
  31. package/lib/agents/index.d.ts +8 -8
  32. package/lib/agents/index.js +13 -30
  33. package/lib/agents/mulmo_prompts_agent.d.ts +1 -1
  34. package/lib/agents/mulmo_prompts_agent.js +7 -11
  35. package/lib/agents/nested_agent.d.ts +9 -0
  36. package/lib/agents/nested_agent.js +138 -0
  37. package/lib/agents/prompts_data.js +1 -4
  38. package/lib/agents/tts_nijivoice_agent.d.ts +1 -1
  39. package/lib/agents/tts_nijivoice_agent.js +8 -12
  40. package/lib/agents/tts_openai_agent.js +9 -16
  41. package/lib/agents/validate_mulmo_script_agent.d.ts +1 -1
  42. package/lib/agents/validate_mulmo_script_agent.js +6 -10
  43. package/lib/cli/args.d.ts +5 -2
  44. package/lib/cli/args.js +52 -35
  45. package/lib/cli/cli.d.ts +14 -0
  46. package/lib/cli/cli.js +74 -57
  47. package/lib/cli/common.js +1 -5
  48. package/lib/cli/tool-args.d.ts +4 -1
  49. package/lib/cli/tool-args.js +29 -18
  50. package/lib/cli/tool-cli.js +34 -51
  51. package/lib/methods/index.d.ts +4 -3
  52. package/lib/methods/index.js +4 -19
  53. package/lib/methods/mulmo_media_source.d.ts +4 -0
  54. package/lib/methods/mulmo_media_source.js +21 -0
  55. package/lib/methods/mulmo_script.d.ts +6 -5
  56. package/lib/methods/mulmo_script.js +29 -16
  57. package/lib/methods/mulmo_script_template.d.ts +1 -1
  58. package/lib/methods/mulmo_script_template.js +4 -10
  59. package/lib/methods/mulmo_studio_context.d.ts +1 -1
  60. package/lib/methods/mulmo_studio_context.js +3 -9
  61. package/lib/tools/create_mulmo_script_from_url.d.ts +3 -0
  62. package/lib/tools/create_mulmo_script_from_url.js +152 -0
  63. package/lib/tools/create_mulmo_script_interactively.d.ts +3 -0
  64. package/lib/tools/create_mulmo_script_interactively.js +258 -0
  65. package/lib/tools/dump_prompt.js +5 -8
  66. package/lib/tools/prompt.js +9 -11
  67. package/lib/tools/seed_from_url2.d.ts +3 -0
  68. package/lib/tools/seed_from_url2.js +154 -0
  69. package/lib/types/index.d.ts +2 -1
  70. package/lib/types/index.js +2 -17
  71. package/lib/types/schema.d.ts +3624 -2798
  72. package/lib/types/schema.js +172 -123
  73. package/lib/types/type.d.ts +34 -3
  74. package/lib/types/type.js +1 -2
  75. package/lib/utils/const.d.ts +4 -1
  76. package/lib/utils/const.js +6 -6
  77. package/lib/utils/file.d.ts +22 -4
  78. package/lib/utils/file.js +100 -79
  79. package/lib/utils/filters.d.ts +1 -0
  80. package/lib/utils/filters.js +47 -26
  81. package/lib/utils/image_plugins/chart.d.ts +3 -0
  82. package/lib/utils/image_plugins/chart.js +18 -0
  83. package/lib/utils/image_plugins/image.d.ts +2 -0
  84. package/lib/utils/image_plugins/image.js +3 -0
  85. package/lib/utils/image_plugins/index.d.ts +7 -0
  86. package/lib/utils/image_plugins/index.js +7 -0
  87. package/lib/utils/image_plugins/markdown.d.ts +3 -0
  88. package/lib/utils/image_plugins/markdown.js +11 -0
  89. package/lib/utils/image_plugins/mermaid.d.ts +3 -0
  90. package/lib/utils/image_plugins/mermaid.js +21 -0
  91. package/lib/utils/image_plugins/movie.d.ts +2 -0
  92. package/lib/utils/image_plugins/movie.js +3 -0
  93. package/lib/utils/image_plugins/source.d.ts +4 -0
  94. package/lib/utils/image_plugins/source.js +15 -0
  95. package/lib/utils/image_plugins/text_slide.d.ts +3 -0
  96. package/lib/utils/image_plugins/text_slide.js +12 -0
  97. package/lib/utils/image_plugins/type_guards.d.ts +6 -0
  98. package/lib/utils/image_plugins/type_guards.js +21 -0
  99. package/lib/utils/image_preprocess.d.ts +14 -0
  100. package/lib/utils/image_preprocess.js +52 -0
  101. package/lib/utils/inquirer.d.ts +2 -0
  102. package/lib/utils/inquirer.js +33 -0
  103. package/lib/utils/markdown.d.ts +3 -1
  104. package/lib/utils/markdown.js +20 -19
  105. package/lib/utils/pdf.d.ts +8 -0
  106. package/lib/utils/pdf.js +75 -0
  107. package/lib/utils/plugins.d.ts +5 -0
  108. package/lib/utils/plugins.js +11 -0
  109. package/lib/utils/preprocess.d.ts +70 -123
  110. package/lib/utils/preprocess.js +37 -43
  111. package/lib/utils/string.js +4 -10
  112. package/lib/utils/text_hash.js +2 -39
  113. package/lib/utils/utils.d.ts +12 -0
  114. package/lib/utils/utils.js +34 -0
  115. package/package.json +23 -8
@@ -1,27 +1,28 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.convertMarkdownToImage = void 0;
7
- const marked_1 = require("marked");
8
- const puppeteer_1 = __importDefault(require("puppeteer"));
9
- const convertMarkdownToImage = async (markdown, style, outputPath) => {
10
- // Step 0: Prepare the header
11
- const header = `<head><style>${style}</style></head>`;
12
- // Step 1: Convert Markdown to HTML
13
- const body = await (0, marked_1.marked)(markdown);
14
- const html = `<htlm>${header}<body>${body}</body></html>`;
15
- // Step 2: Use Puppeteer to render HTML to an image
16
- const browser = await puppeteer_1.default.launch();
1
+ import { GraphAILogger } from "graphai";
2
+ import { marked } from "marked";
3
+ import puppeteer from "puppeteer";
4
+ const isCI = process.env.CI === "true";
5
+ export const renderHTMLToImage = async (html, outputPath, width, height) => {
6
+ // Use Puppeteer to render HTML to an image
7
+ const browser = await puppeteer.launch({
8
+ args: isCI ? ["--no-sandbox"] : [],
9
+ });
17
10
  const page = await browser.newPage();
18
11
  // Set the page content to the HTML generated from the Markdown
19
12
  await page.setContent(html);
20
13
  // Adjust page settings if needed (like width, height, etc.)
21
- await page.setViewport({ width: 1200, height: 800 });
14
+ await page.setViewport({ width, height });
22
15
  // Step 3: Capture screenshot of the page (which contains the Markdown-rendered HTML)
23
16
  await page.screenshot({ path: outputPath });
24
17
  await browser.close();
25
- console.log(`Image saved to ${outputPath}`);
18
+ GraphAILogger.info(`HTML image rendered to ${outputPath}`);
19
+ };
20
+ export const renderMarkdownToImage = async (markdown, style, outputPath, width, height) => {
21
+ const header = `<head><style>${style}</style></head>`;
22
+ const body = await marked(markdown);
23
+ const html = `<htlm>${header}<body>${body}</body></html>`;
24
+ await renderHTMLToImage(html, outputPath, width, height);
25
+ };
26
+ export const interpolate = (template, data) => {
27
+ return template.replace(/\$\{(.*?)\}/g, (_, key) => data[key.trim()] ?? "");
26
28
  };
27
- exports.convertMarkdownToImage = convertMarkdownToImage;
@@ -0,0 +1,8 @@
1
+ import { PDFFont } from "pdf-lib";
2
+ export declare const fontSize = 12;
3
+ export declare const textMargin = 6;
4
+ export declare const drawSize: (fitWidth: boolean, expectWidth: number, expectHeight: number, origWidth: number, origHeight: number) => {
5
+ drawWidth: number;
6
+ drawHeight: number;
7
+ };
8
+ export declare const wrapText: (text: string, font: PDFFont, fontSize: number, maxWidth: number) => string[];
@@ -0,0 +1,75 @@
1
+ export const fontSize = 12;
2
+ export const textMargin = 6;
3
+ export const drawSize = (fitWidth, expectWidth, expectHeight, origWidth, origHeight) => {
4
+ if (fitWidth) {
5
+ const drawWidth = expectWidth;
6
+ const scale = drawWidth / origWidth;
7
+ const drawHeight = origHeight * scale;
8
+ return {
9
+ drawWidth,
10
+ drawHeight,
11
+ };
12
+ }
13
+ const drawHeight = expectHeight;
14
+ const scale = drawHeight / origHeight;
15
+ const drawWidth = origWidth * scale;
16
+ return {
17
+ drawWidth,
18
+ drawHeight,
19
+ };
20
+ };
21
+ const isFullwidth = (char) => {
22
+ const code = char.charCodeAt(0);
23
+ return ((code >= 0x3000 && code <= 0x9fff) || // CJK, punctuation, kana
24
+ (code >= 0xff00 && code <= 0xffef) // Fullwidth ASCII
25
+ );
26
+ };
27
+ export const wrapText = (text, font, fontSize, maxWidth) => {
28
+ const lines = [];
29
+ for (const rawLine of text.split("\n")) {
30
+ let line = "";
31
+ let buffer = "";
32
+ for (let i = 0; i < rawLine.length; i++) {
33
+ const char = rawLine[i];
34
+ buffer += char;
35
+ const width = font.widthOfTextAtSize(line + buffer, fontSize);
36
+ const nextChar = rawLine[i + 1];
37
+ const currentIsFull = isFullwidth(char);
38
+ const nextIsFull = nextChar && isFullwidth(nextChar);
39
+ const isBreakable = currentIsFull || (!currentIsFull && (char === " " || nextChar === " " || nextIsFull));
40
+ if (width > maxWidth && buffer) {
41
+ lines.push(line);
42
+ line = "";
43
+ buffer = char;
44
+ }
45
+ if (isBreakable || i === rawLine.length - 1) {
46
+ line += buffer;
47
+ buffer = "";
48
+ }
49
+ }
50
+ if (line)
51
+ lines.push(line);
52
+ }
53
+ return lines;
54
+ };
55
+ /*
56
+ export const wrapText = (text: string, font: PDFFont, fontSize: number, maxWidth: number) => {
57
+ const words = text.split(" ");
58
+ const lines = [];
59
+ let currentLine = "";
60
+
61
+ for (const word of words) {
62
+ const nextLine = currentLine ? `${currentLine} ${word}` : word;
63
+ // console.log(nextLine);
64
+ const width = font.widthOfTextAtSize(nextLine ?? "", fontSize);
65
+ if (width <= maxWidth) {
66
+ currentLine = nextLine;
67
+ } else {
68
+ lines.push(currentLine);
69
+ currentLine = word;
70
+ }
71
+ }
72
+ if (currentLine) lines.push(currentLine);
73
+ return lines;
74
+ };
75
+ */
@@ -0,0 +1,5 @@
1
+ import { TransactionLog } from "graphai";
2
+ export declare const cliLoadingPlugin: ({ nodeId, message }: {
3
+ nodeId: string;
4
+ message: string;
5
+ }) => (log: TransactionLog) => void;
@@ -0,0 +1,11 @@
1
+ import ora from "ora";
2
+ const spinner = ora();
3
+ spinner.prefixText = "\n";
4
+ export const cliLoadingPlugin = ({ nodeId, message }) => (log) => {
5
+ if (log.nodeId === nodeId && log.state === "queued") {
6
+ spinner.start(message);
7
+ }
8
+ if (log.nodeId === nodeId && log.state === "completed") {
9
+ spinner.stop();
10
+ }
11
+ };
@@ -1,101 +1,7 @@
1
- export declare const createOrUpdateStudioData: (mulmoFile: string, files: {
2
- outDirPath: string;
3
- }) => {
1
+ import { MulmoStudio, MulmoScript } from "../types/index.js";
2
+ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, currentStudio: MulmoStudio | undefined, fileName: string) => {
4
3
  beats: {
5
- text: string;
6
- speaker: string;
7
4
  duration?: number | undefined;
8
- speechOptions?: {
9
- speed?: number | undefined;
10
- instruction?: string | undefined;
11
- } | undefined;
12
- image?: {
13
- type: "markdown";
14
- markdown: string | string[];
15
- } | {
16
- type: "web";
17
- url: string;
18
- } | {
19
- type: "pdf";
20
- source: {
21
- url: string;
22
- kind: "url";
23
- } | {
24
- kind: "data";
25
- data: string;
26
- } | {
27
- path: string;
28
- kind: "path";
29
- };
30
- } | {
31
- type: "image";
32
- source: {
33
- url: string;
34
- kind: "url";
35
- } | {
36
- kind: "data";
37
- data: string;
38
- } | {
39
- path: string;
40
- kind: "path";
41
- };
42
- } | {
43
- type: "svg";
44
- source: {
45
- url: string;
46
- kind: "url";
47
- } | {
48
- kind: "data";
49
- data: string;
50
- } | {
51
- path: string;
52
- kind: "path";
53
- };
54
- } | {
55
- type: "movie";
56
- source: {
57
- url: string;
58
- kind: "url";
59
- } | {
60
- kind: "data";
61
- data: string;
62
- } | {
63
- path: string;
64
- kind: "path";
65
- };
66
- } | {
67
- type: "textSlide";
68
- slide: {
69
- title: string;
70
- bullets: string[];
71
- };
72
- } | undefined;
73
- audio?: {
74
- type: "audio";
75
- source: {
76
- url: string;
77
- kind: "url";
78
- } | {
79
- kind: "data";
80
- data: string;
81
- } | {
82
- path: string;
83
- kind: "path";
84
- };
85
- } | {
86
- type: "midi";
87
- source: string;
88
- } | undefined;
89
- imageParams?: {
90
- model?: string | undefined;
91
- size?: string | undefined;
92
- style?: string | undefined;
93
- moderation?: string | undefined;
94
- } | undefined;
95
- textSlideParams?: {
96
- cssStyles: string[];
97
- } | undefined;
98
- imagePrompt?: string | undefined;
99
5
  multiLingualTexts?: Record<string, {
100
6
  text: string;
101
7
  lang: string;
@@ -108,11 +14,25 @@ export declare const createOrUpdateStudioData: (mulmoFile: string, files: {
108
14
  imageFile?: string | undefined;
109
15
  }[];
110
16
  script: {
111
- title: string;
112
17
  $mulmocast: {
113
18
  version: "1.0";
114
19
  credit?: "closing" | undefined;
115
20
  };
21
+ canvasSize: {
22
+ width: number;
23
+ height: number;
24
+ };
25
+ speechParams: {
26
+ provider: "openai" | "nijivoice";
27
+ speakers: Record<string, {
28
+ voiceId: string;
29
+ displayName?: Record<string, string> | undefined;
30
+ speechOptions?: {
31
+ speed?: number | undefined;
32
+ instruction?: string | undefined;
33
+ } | undefined;
34
+ }>;
35
+ };
116
36
  beats: {
117
37
  text: string;
118
38
  speaker: string;
@@ -132,8 +52,11 @@ export declare const createOrUpdateStudioData: (mulmoFile: string, files: {
132
52
  url: string;
133
53
  kind: "url";
134
54
  } | {
135
- kind: "data";
55
+ kind: "base64";
136
56
  data: string;
57
+ } | {
58
+ text: string;
59
+ kind: "text";
137
60
  } | {
138
61
  path: string;
139
62
  kind: "path";
@@ -144,8 +67,11 @@ export declare const createOrUpdateStudioData: (mulmoFile: string, files: {
144
67
  url: string;
145
68
  kind: "url";
146
69
  } | {
147
- kind: "data";
70
+ kind: "base64";
148
71
  data: string;
72
+ } | {
73
+ text: string;
74
+ kind: "text";
149
75
  } | {
150
76
  path: string;
151
77
  kind: "path";
@@ -156,8 +82,11 @@ export declare const createOrUpdateStudioData: (mulmoFile: string, files: {
156
82
  url: string;
157
83
  kind: "url";
158
84
  } | {
159
- kind: "data";
85
+ kind: "base64";
160
86
  data: string;
87
+ } | {
88
+ text: string;
89
+ kind: "text";
161
90
  } | {
162
91
  path: string;
163
92
  kind: "path";
@@ -168,8 +97,11 @@ export declare const createOrUpdateStudioData: (mulmoFile: string, files: {
168
97
  url: string;
169
98
  kind: "url";
170
99
  } | {
171
- kind: "data";
100
+ kind: "base64";
172
101
  data: string;
102
+ } | {
103
+ text: string;
104
+ kind: "text";
173
105
  } | {
174
106
  path: string;
175
107
  kind: "path";
@@ -180,6 +112,27 @@ export declare const createOrUpdateStudioData: (mulmoFile: string, files: {
180
112
  title: string;
181
113
  bullets: string[];
182
114
  };
115
+ } | {
116
+ type: "chart";
117
+ title: string;
118
+ chartData: Record<string, any>;
119
+ } | {
120
+ code: {
121
+ url: string;
122
+ kind: "url";
123
+ } | {
124
+ kind: "base64";
125
+ data: string;
126
+ } | {
127
+ text: string;
128
+ kind: "text";
129
+ } | {
130
+ path: string;
131
+ kind: "path";
132
+ };
133
+ type: "mermaid";
134
+ title: string;
135
+ appendix?: string[] | undefined;
183
136
  } | undefined;
184
137
  audio?: {
185
138
  type: "audio";
@@ -187,8 +140,11 @@ export declare const createOrUpdateStudioData: (mulmoFile: string, files: {
187
140
  url: string;
188
141
  kind: "url";
189
142
  } | {
190
- kind: "data";
143
+ kind: "base64";
191
144
  data: string;
145
+ } | {
146
+ text: string;
147
+ kind: "text";
192
148
  } | {
193
149
  path: string;
194
150
  kind: "path";
@@ -204,43 +160,34 @@ export declare const createOrUpdateStudioData: (mulmoFile: string, files: {
204
160
  moderation?: string | undefined;
205
161
  } | undefined;
206
162
  textSlideParams?: {
207
- cssStyles: string[];
163
+ cssStyles: string | string[];
208
164
  } | undefined;
209
165
  imagePrompt?: string | undefined;
210
166
  }[];
211
- speechParams: {
212
- speakers: Record<string, {
213
- displayName: Record<string, string>;
214
- voiceId: string;
215
- speechOptions?: {
216
- speed?: number | undefined;
217
- instruction?: string | undefined;
218
- } | undefined;
219
- }>;
220
- provider?: string | undefined;
221
- };
222
167
  lang?: string | undefined;
168
+ title?: string | undefined;
223
169
  imageParams?: {
170
+ provider: "openai" | "google";
224
171
  model?: string | undefined;
225
172
  size?: string | undefined;
226
173
  style?: string | undefined;
227
174
  moderation?: string | undefined;
228
- provider?: string | undefined;
229
175
  } | undefined;
230
176
  textSlideParams?: {
231
- cssStyles: string[];
232
- } | undefined;
233
- description?: string | undefined;
234
- reference?: string | undefined;
235
- canvasSize?: {
236
- width: number;
237
- height: number;
177
+ cssStyles: string | string[];
238
178
  } | undefined;
239
179
  videoParams?: {
240
180
  padding?: number | undefined;
241
181
  } | undefined;
242
- imagePath?: string | undefined;
243
182
  omitCaptions?: boolean | undefined;
183
+ description?: string | undefined;
184
+ references?: {
185
+ type: "image" | "audio" | "article" | "video";
186
+ url: string;
187
+ title?: string | undefined;
188
+ description?: string | undefined;
189
+ }[] | undefined;
190
+ imagePath?: string | undefined;
244
191
  __test_invalid__?: boolean | undefined;
245
192
  };
246
193
  filename: string;
@@ -1,53 +1,47 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createOrUpdateStudioData = void 0;
4
- const file_1 = require("./file");
5
- const text_hash_1 = require("./text_hash");
6
- const methods_1 = require("../methods");
7
- const createOrUpdateStudioData = (mulmoFile, files) => {
8
- const { outDirPath } = files;
9
- const readData = (0, file_1.readMulmoScriptFile)(mulmoFile, "ERROR: File does not exist " + mulmoFile);
10
- const { mulmoData: mulmoScript, fileName } = readData;
11
- // Create or update MulmoStudio file with MulmoScript
12
- const outputStudioFilePath = (0, file_1.getOutputStudioFilePath)(outDirPath, fileName);
13
- const currentStudio = (0, file_1.readMulmoScriptFile)(outputStudioFilePath);
14
- const studio = currentStudio?.mulmoData ?? {
1
+ import { mulmoScriptSchema, mulmoBeatSchema, mulmoStudioSchema } from "../types/index.js";
2
+ const rebuildStudio = (currentStudio, mulmoScript, fileName) => {
3
+ const parsed = mulmoStudioSchema.safeParse(currentStudio);
4
+ if (parsed.success) {
5
+ return parsed.data;
6
+ }
7
+ return {
15
8
  script: mulmoScript,
16
9
  filename: fileName,
17
- beats: Array(mulmoScript.beats.length).fill({}),
10
+ beats: [...Array(mulmoScript.beats.length)].map(() => ({})),
18
11
  };
19
- if (!studio.beats) {
20
- studio.beats = [];
21
- }
22
- // Addition cloing credit
23
- if (mulmoScript.$mulmocast.credit === "closing") {
24
- mulmoScript.beats.push({
25
- speaker: mulmoScript.beats[0].speaker, // First speaker
26
- text: "",
27
- image: {
28
- type: "image",
29
- source: {
30
- kind: "url",
31
- url: "https://github.com/receptron/mulmocast-cli/raw/refs/heads/main/assets/images/mulmocast_credit.png",
32
- },
12
+ };
13
+ const mulmoCredit = (speaker) => {
14
+ return {
15
+ speaker,
16
+ text: "",
17
+ image: {
18
+ type: "image",
19
+ source: {
20
+ kind: "url",
21
+ url: "https://github.com/receptron/mulmocast-cli/raw/refs/heads/main/assets/images/mulmocast_credit.png",
33
22
  },
34
- audio: {
35
- type: "audio",
36
- source: {
37
- kind: "url",
38
- url: "https://github.com/receptron/mulmocast-cli/raw/refs/heads/main/assets/audio/silent300.mp3",
39
- },
23
+ },
24
+ audio: {
25
+ type: "audio",
26
+ source: {
27
+ kind: "url",
28
+ url: "https://github.com/receptron/mulmocast-cli/raw/refs/heads/main/assets/audio/silent300.mp3",
40
29
  },
41
- });
30
+ },
31
+ };
32
+ };
33
+ export const createOrUpdateStudioData = (_mulmoScript, currentStudio, fileName) => {
34
+ const mulmoScript = _mulmoScript.__test_invalid__ ? _mulmoScript : mulmoScriptSchema.parse(_mulmoScript); // validate and insert default value
35
+ const studio = rebuildStudio(currentStudio, mulmoScript, fileName);
36
+ // Addition cloing credit
37
+ if (mulmoScript.$mulmocast.credit === "closing") {
38
+ mulmoScript.beats.push(mulmoCredit(mulmoScript.beats[0].speaker)); // First speaker
42
39
  }
43
- studio.script = mulmoScript; // update the script
44
- studio.beats.length = mulmoScript.beats.length; // In case it became shorter
40
+ studio.script = mulmoScriptSchema.parse(mulmoScript); // update the script
41
+ studio.beats = studio.script.beats.map((_, index) => studio.beats[index] ?? {});
45
42
  mulmoScript.beats.forEach((beat, index) => {
46
- const voiceId = studio.script.speechParams.speakers[beat.speaker].voiceId;
47
- const speechOptions = methods_1.MulmoScriptMethods.getSpeechOptions(studio.script, beat);
48
- const hash_string = `${beat.text}${voiceId}${speechOptions?.instruction ?? ""}${speechOptions?.speed ?? 1.0}`;
49
- studio.beats[index] = { ...studio.beats[index], ...beat, audioFile: `${fileName}_${index}_${(0, text_hash_1.text2hash)(hash_string)}` };
43
+ // Filling the default values
44
+ studio.script.beats[index] = mulmoBeatSchema.parse(beat);
50
45
  });
51
46
  return studio;
52
47
  };
53
- exports.createOrUpdateStudioData = createOrUpdateStudioData;
@@ -1,10 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.replacementsJa = exports.recursiveSplitJa = void 0;
4
- exports.splitIntoSentencesJa = splitIntoSentencesJa;
5
- exports.replacePairsJa = replacePairsJa;
6
1
  // split ja
7
- function splitIntoSentencesJa(paragraph, divider, minimum) {
2
+ export function splitIntoSentencesJa(paragraph, divider, minimum) {
8
3
  const sentences = paragraph
9
4
  .split(divider) // Split by the Japanese full stop
10
5
  .map((sentence) => sentence.trim()) // Trim whitespace
@@ -21,7 +16,7 @@ function splitIntoSentencesJa(paragraph, divider, minimum) {
21
16
  }, [])
22
17
  .map((sentence, index, array) => (index < array.length - 1 || paragraph.endsWith(divider) ? sentence + divider : sentence));
23
18
  }
24
- const recursiveSplitJa = (text) => {
19
+ export const recursiveSplitJa = (text) => {
25
20
  const delimiters = ["。", "?", "!", "、"];
26
21
  return delimiters
27
22
  .reduce((textData, delimiter) => {
@@ -29,8 +24,7 @@ const recursiveSplitJa = (text) => {
29
24
  }, [text])
30
25
  .flat(1);
31
26
  };
32
- exports.recursiveSplitJa = recursiveSplitJa;
33
- function replacePairsJa(str, replacements) {
27
+ export function replacePairsJa(str, replacements) {
34
28
  replacements.forEach(({ from, to }) => {
35
29
  // Escape any special regex characters in the 'from' string.
36
30
  const escapedFrom = from.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -39,7 +33,7 @@ function replacePairsJa(str, replacements) {
39
33
  });
40
34
  return str;
41
35
  }
42
- exports.replacementsJa = [
36
+ export const replacementsJa = [
43
37
  { from: "Anthropic", to: "アンスロピック" },
44
38
  { from: "OpenAI", to: "オープンエーアイ" },
45
39
  { from: "AGI", to: "エージーアイ" },
@@ -1,41 +1,4 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.text2hash = void 0;
37
- const crypto = __importStar(require("crypto"));
38
- const text2hash = (input) => {
1
+ import * as crypto from "crypto";
2
+ export const text2hash = (input) => {
39
3
  return crypto.createHash("sha256").update(input).digest("hex");
40
4
  };
41
- exports.text2hash = text2hash;
@@ -0,0 +1,12 @@
1
+ export declare const llmAgents: string[];
2
+ type LLMAgent = (typeof llmAgents)[number];
3
+ export declare const defaultOpenAIModel: string;
4
+ export declare const llmPair: (_agent?: LLMAgent, _model?: string) => {
5
+ agent: string;
6
+ model: string;
7
+ max_tokens: number;
8
+ };
9
+ export declare const chunkArray: <T>(array: T[], size?: number) => T[][];
10
+ export declare const isHttp: (fileOrUrl: string) => boolean;
11
+ export declare const text2hash: (input: string) => string;
12
+ export {};
@@ -0,0 +1,34 @@
1
+ import * as crypto from "crypto";
2
+ export const llmAgents = ["openAIAgent", "anthropicAgent", "geminiAgent", "groqAgent"];
3
+ const defaultModels = {
4
+ anthropicAgent: "claude-3-7-sonnet-20250219",
5
+ geminiAgent: "gemini-1.5-flash",
6
+ groqAgent: "llama3-8b-8192",
7
+ openAIAgent: "gpt-4o",
8
+ };
9
+ const longMaxTokens = {
10
+ anthropicAgent: 8192,
11
+ geminiAgent: 8192,
12
+ groqAgent: 4096,
13
+ openAIAgent: 8192,
14
+ };
15
+ export const defaultOpenAIModel = defaultModels["openAIAgent"];
16
+ export const llmPair = (_agent, _model) => {
17
+ const agent = _agent && llmAgents.includes(_agent ?? "") ? _agent : "openAIAgent";
18
+ const model = _model ?? defaultModels[agent ?? ""];
19
+ const max_tokens = longMaxTokens[agent];
20
+ return { agent, model, max_tokens };
21
+ };
22
+ export const chunkArray = (array, size = 3) => {
23
+ const chunks = [];
24
+ const copy = [...array];
25
+ while (copy.length)
26
+ chunks.push(copy.splice(0, size));
27
+ return chunks;
28
+ };
29
+ export const isHttp = (fileOrUrl) => {
30
+ return /^https?:\/\//.test(fileOrUrl);
31
+ };
32
+ export const text2hash = (input) => {
33
+ return crypto.createHash("sha256").update(input).digest("hex");
34
+ };