mulmocast 2.9.1 → 2.9.2

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 (117) hide show
  1. package/lib/agents/image_google_agent.d.ts +5 -0
  2. package/lib/agents/image_google_agent.js +86 -0
  3. package/lib/agents/movie_google_agent.d.ts +9 -0
  4. package/lib/agents/movie_google_agent.js +122 -0
  5. package/lib/agents/mulmo_prompts_agent.d.ts +7 -0
  6. package/lib/agents/mulmo_prompts_agent.js +37 -0
  7. package/lib/agents/prompts_data.d.ts +15 -0
  8. package/lib/agents/prompts_data.js +16 -0
  9. package/lib/agents/tts_nijivoice_agent.d.ts +5 -0
  10. package/lib/agents/tts_nijivoice_agent.js +69 -0
  11. package/lib/agents/validate_mulmo_script_agent.d.ts +17 -0
  12. package/lib/agents/validate_mulmo_script_agent.js +34 -0
  13. package/lib/cli/args.d.ts +15 -0
  14. package/lib/cli/args.js +62 -0
  15. package/lib/cli/bin.js +0 -0
  16. package/lib/cli/cli.d.ts +17 -0
  17. package/lib/cli/cli.js +117 -0
  18. package/lib/cli/run.d.ts +2 -0
  19. package/lib/cli/run.js +3 -0
  20. package/lib/cli/tool-args.d.ts +16 -0
  21. package/lib/cli/tool-args.js +64 -0
  22. package/lib/cli/tool-cli.d.ts +2 -0
  23. package/lib/cli/tool-cli.js +32 -0
  24. package/lib/cli/tool_commands/prompt/builder.d.ts +4 -0
  25. package/lib/cli/tool_commands/prompt/builder.js +11 -0
  26. package/lib/cli/tool_commands/prompt/handler.d.ts +4 -0
  27. package/lib/cli/tool_commands/prompt/handler.js +14 -0
  28. package/lib/cli/tool_commands/prompt/index.d.ts +4 -0
  29. package/lib/cli/tool_commands/prompt/index.js +4 -0
  30. package/lib/cli/tool_commands/schema/builder.d.ts +2 -0
  31. package/lib/cli/tool_commands/schema/builder.js +3 -0
  32. package/lib/cli/tool_commands/schema/handler.d.ts +2 -0
  33. package/lib/cli/tool_commands/schema/handler.js +12 -0
  34. package/lib/cli/tool_commands/schema/index.d.ts +4 -0
  35. package/lib/cli/tool_commands/schema/index.js +4 -0
  36. package/lib/cli/tool_commands/scripting/builder.d.ts +20 -0
  37. package/lib/cli/tool_commands/scripting/builder.js +63 -0
  38. package/lib/cli/tool_commands/scripting/handler.d.ts +12 -0
  39. package/lib/cli/tool_commands/scripting/handler.js +36 -0
  40. package/lib/cli/tool_commands/scripting/index.d.ts +4 -0
  41. package/lib/cli/tool_commands/scripting/index.js +4 -0
  42. package/lib/index.d.ts +8 -0
  43. package/lib/index.js +8 -0
  44. package/lib/methods/mulmo_script_template.d.ts +4 -0
  45. package/lib/methods/mulmo_script_template.js +6 -0
  46. package/lib/methods/mulmo_studio.d.ts +8 -0
  47. package/lib/methods/mulmo_studio.js +25 -0
  48. package/lib/slide/blocks.d.ts +13 -0
  49. package/lib/slide/blocks.js +251 -0
  50. package/lib/slide/index.d.ts +6 -0
  51. package/lib/slide/index.js +7 -0
  52. package/lib/slide/layouts/big_quote.d.ts +2 -0
  53. package/lib/slide/layouts/big_quote.js +19 -0
  54. package/lib/slide/layouts/columns.d.ts +2 -0
  55. package/lib/slide/layouts/columns.js +53 -0
  56. package/lib/slide/layouts/comparison.d.ts +2 -0
  57. package/lib/slide/layouts/comparison.js +25 -0
  58. package/lib/slide/layouts/funnel.d.ts +2 -0
  59. package/lib/slide/layouts/funnel.js +25 -0
  60. package/lib/slide/layouts/grid.d.ts +2 -0
  61. package/lib/slide/layouts/grid.js +38 -0
  62. package/lib/slide/layouts/index.d.ts +3 -0
  63. package/lib/slide/layouts/index.js +46 -0
  64. package/lib/slide/layouts/matrix.d.ts +2 -0
  65. package/lib/slide/layouts/matrix.js +53 -0
  66. package/lib/slide/layouts/split.d.ts +2 -0
  67. package/lib/slide/layouts/split.js +51 -0
  68. package/lib/slide/layouts/stats.d.ts +2 -0
  69. package/lib/slide/layouts/stats.js +23 -0
  70. package/lib/slide/layouts/table.d.ts +2 -0
  71. package/lib/slide/layouts/table.js +10 -0
  72. package/lib/slide/layouts/timeline.d.ts +2 -0
  73. package/lib/slide/layouts/timeline.js +27 -0
  74. package/lib/slide/layouts/title.d.ts +2 -0
  75. package/lib/slide/layouts/title.js +19 -0
  76. package/lib/slide/layouts/waterfall.d.ts +2 -0
  77. package/lib/slide/layouts/waterfall.js +63 -0
  78. package/lib/slide/render.d.ts +17 -0
  79. package/lib/slide/render.js +101 -0
  80. package/lib/slide/schema.d.ts +9309 -0
  81. package/lib/slide/schema.js +434 -0
  82. package/lib/slide/utils.d.ts +76 -0
  83. package/lib/slide/utils.js +243 -0
  84. package/lib/tools/prompt.d.ts +1 -0
  85. package/lib/tools/prompt.js +18 -0
  86. package/lib/tools/seed.d.ts +3 -0
  87. package/lib/tools/seed.js +211 -0
  88. package/lib/tools/seed_from_url.d.ts +3 -0
  89. package/lib/tools/seed_from_url.js +188 -0
  90. package/lib/types/slide.d.ts +9309 -0
  91. package/lib/types/slide.js +434 -0
  92. package/lib/utils/assets.d.ts +18 -0
  93. package/lib/utils/assets.js +101 -0
  94. package/lib/utils/cli.d.ts +1 -0
  95. package/lib/utils/cli.js +15 -0
  96. package/lib/utils/const.d.ts +12 -0
  97. package/lib/utils/const.js +12 -0
  98. package/lib/utils/filters.js +11 -2
  99. package/lib/utils/image_preprocess.d.ts +14 -0
  100. package/lib/utils/image_preprocess.js +52 -0
  101. package/lib/utils/markdown.d.ts +3 -0
  102. package/lib/utils/markdown.js +42 -0
  103. package/lib/utils/pdf.d.ts +9 -0
  104. package/lib/utils/pdf.js +77 -0
  105. package/lib/utils/preprocess.d.ts +343 -0
  106. package/lib/utils/preprocess.js +58 -0
  107. package/lib/utils/provider2agent.d.ts +141 -0
  108. package/lib/utils/provider2agent.js +267 -0
  109. package/lib/utils/text_hash.d.ts +1 -0
  110. package/lib/utils/text_hash.js +4 -0
  111. package/package.json +1 -1
  112. package/lib/utils/sdk_timeout.d.ts +0 -3
  113. package/lib/utils/sdk_timeout.js +0 -7
  114. package/scripts/test/test_captions_2.json~ +0 -278
  115. package/scripts/test/test_en_portrait.json~ +0 -31
  116. package/scripts/test/test_slide_image_ref_gemini_en.json~ +0 -289
  117. package/scripts/test/test_vertexai.json~ +0 -21
@@ -0,0 +1,5 @@
1
+ import type { AgentFunction, AgentFunctionInfo } from "graphai";
2
+ import type { AgentBufferResult, ImageAgentInputs, ImageAgentParams, GoogleImageAgentConfig } from "../types/agent.js";
3
+ export declare const imageGoogleAgent: AgentFunction<ImageAgentParams, AgentBufferResult, ImageAgentInputs, GoogleImageAgentConfig>;
4
+ declare const imageGoogleAgentInfo: AgentFunctionInfo;
5
+ export default imageGoogleAgentInfo;
@@ -0,0 +1,86 @@
1
+ import { GraphAILogger } from "graphai";
2
+ import { getAspectRatio } from "./movie_google_agent.js";
3
+ import { provider2ImageAgent } from "../utils/provider2agent.js";
4
+ async function generateImage(projectId, model, token, prompt, aspectRatio) {
5
+ const GOOGLE_IMAGEN_ENDPOINT = `https://us-central1-aiplatform.googleapis.com/v1/projects/${projectId}/locations/us-central1/publishers/google/models/${model}:predict`;
6
+ try {
7
+ // Prepare the payload for the API request
8
+ const payload = {
9
+ instances: [
10
+ {
11
+ prompt,
12
+ },
13
+ ],
14
+ parameters: {
15
+ sampleCount: 1,
16
+ aspectRatio,
17
+ safetySetting: "block_only_high",
18
+ },
19
+ };
20
+ // Make the API call using fetch
21
+ const response = await fetch(GOOGLE_IMAGEN_ENDPOINT, {
22
+ method: "POST",
23
+ headers: {
24
+ Authorization: `Bearer ${token}`,
25
+ "Content-Type": "application/json",
26
+ },
27
+ body: JSON.stringify(payload),
28
+ });
29
+ if (!response.ok) {
30
+ throw new Error(`Error: ${response.status} - ${response.statusText}`);
31
+ }
32
+ const responseData = await response.json();
33
+ // Parse and return the generated image URL or data
34
+ const predictions = responseData.predictions;
35
+ if (predictions && predictions.length > 0) {
36
+ const base64Image = predictions[0].bytesBase64Encoded;
37
+ if (base64Image) {
38
+ return Buffer.from(base64Image, "base64"); // Decode the base64 image to a buffer
39
+ }
40
+ else {
41
+ throw new Error("No base64-encoded image data returned from the API.");
42
+ }
43
+ }
44
+ else {
45
+ // console.log(response);
46
+ GraphAILogger.info("No predictions returned from the API.", responseData, prompt);
47
+ return undefined;
48
+ }
49
+ }
50
+ catch (error) {
51
+ GraphAILogger.info("Error generating image:", error);
52
+ throw error;
53
+ }
54
+ }
55
+ export const imageGoogleAgent = async ({ namedInputs, params, config, }) => {
56
+ const { prompt } = namedInputs;
57
+ const aspectRatio = getAspectRatio(params.canvasSize);
58
+ const model = params.model ?? provider2ImageAgent["google"].defaultModel;
59
+ const projectId = config?.projectId;
60
+ const token = config?.token;
61
+ try {
62
+ const buffer = await generateImage(projectId, model, token, prompt, aspectRatio);
63
+ if (buffer) {
64
+ return { buffer };
65
+ }
66
+ throw new Error("ERROR: geneateImage returned undefined");
67
+ }
68
+ catch (error) {
69
+ GraphAILogger.info("Failed to generate image:", error);
70
+ throw error;
71
+ }
72
+ };
73
+ const imageGoogleAgentInfo = {
74
+ name: "imageGoogleAgent",
75
+ agent: imageGoogleAgent,
76
+ mock: imageGoogleAgent,
77
+ samples: [],
78
+ description: "Google Image agent",
79
+ category: ["image"],
80
+ author: "Receptron Team",
81
+ repository: "https://github.com/receptron/mulmocast-cli/",
82
+ // source: "https://github.com/receptron/mulmocast-cli/blob/main/src/agents/image_google_agent.ts",
83
+ license: "MIT",
84
+ environmentVariables: [],
85
+ };
86
+ export default imageGoogleAgentInfo;
@@ -0,0 +1,9 @@
1
+ import type { AgentFunction, AgentFunctionInfo } from "graphai";
2
+ import type { AgentBufferResult, GoogleImageAgentConfig, GoogleMovieAgentParams, MovieAgentInputs } from "../types/agent.js";
3
+ export declare const getAspectRatio: (canvasSize: {
4
+ width: number;
5
+ height: number;
6
+ }) => string;
7
+ export declare const movieGoogleAgent: AgentFunction<GoogleMovieAgentParams, AgentBufferResult, MovieAgentInputs, GoogleImageAgentConfig>;
8
+ declare const movieGoogleAgentInfo: AgentFunctionInfo;
9
+ export default movieGoogleAgentInfo;
@@ -0,0 +1,122 @@
1
+ import { readFileSync } from "fs";
2
+ import { GraphAILogger, sleep } from "graphai";
3
+ async function generateMovie(projectId, model, token, prompt, imagePath, aspectRatio, duration) {
4
+ const GOOGLE_IMAGEN_ENDPOINT = `https://us-central1-aiplatform.googleapis.com/v1/projects/${projectId}/locations/us-central1/publishers/google/models/${model}`;
5
+ const payload = {
6
+ instances: [
7
+ {
8
+ prompt,
9
+ image: undefined,
10
+ },
11
+ ],
12
+ parameters: {
13
+ sampleCount: 1,
14
+ aspectRatio,
15
+ safetySetting: "block_only_high",
16
+ personGeneration: "allow_all",
17
+ durationSeconds: duration,
18
+ },
19
+ };
20
+ if (imagePath) {
21
+ const buffer = readFileSync(imagePath);
22
+ const bytesBase64Encoded = buffer.toString("base64");
23
+ payload.instances[0].image = {
24
+ bytesBase64Encoded,
25
+ mimeType: "image/png",
26
+ };
27
+ }
28
+ // Make the API call using fetch
29
+ const response = await fetch(`${GOOGLE_IMAGEN_ENDPOINT}:predictLongRunning`, {
30
+ method: "POST",
31
+ headers: {
32
+ Authorization: `Bearer ${token}`,
33
+ "Content-Type": "application/json",
34
+ },
35
+ body: JSON.stringify(payload),
36
+ });
37
+ if (!response.ok) {
38
+ GraphAILogger.info("create project on google cloud console and setup the project. More details see readme.");
39
+ throw new Error(`Error: ${response.status} - ${response.statusText}`);
40
+ }
41
+ const initialResponse = await response.json();
42
+ const fetchBody = {
43
+ operationName: initialResponse.name,
44
+ };
45
+ const completeResponse = await (async () => {
46
+ while (true) {
47
+ GraphAILogger.info("...waiting for movie generation...");
48
+ await sleep(3000);
49
+ const operationResponse = await fetch(`${GOOGLE_IMAGEN_ENDPOINT}:fetchPredictOperation`, {
50
+ method: "POST",
51
+ headers: {
52
+ Authorization: `Bearer ${token}`,
53
+ "Content-Type": "application/json",
54
+ },
55
+ body: JSON.stringify(fetchBody),
56
+ });
57
+ if (!operationResponse.ok) {
58
+ throw new Error(`Error: ${operationResponse.status} - ${operationResponse.statusText}`);
59
+ }
60
+ const responseData = await operationResponse.json();
61
+ if (responseData.done) {
62
+ if (responseData.error) {
63
+ GraphAILogger.info("Prompt: ", prompt);
64
+ throw new Error(`Error: ${responseData.error.message}`);
65
+ }
66
+ if (!responseData.response.videos) {
67
+ throw new Error(`No video: ${JSON.stringify(responseData, null, 2)}`);
68
+ }
69
+ return responseData.response;
70
+ }
71
+ }
72
+ })();
73
+ const encodedMovie = completeResponse.videos[0].bytesBase64Encoded;
74
+ if (encodedMovie) {
75
+ return Buffer.from(encodedMovie, "base64");
76
+ }
77
+ return undefined;
78
+ }
79
+ export const getAspectRatio = (canvasSize) => {
80
+ if (canvasSize.width > canvasSize.height) {
81
+ return "16:9";
82
+ }
83
+ else if (canvasSize.width < canvasSize.height) {
84
+ return "9:16";
85
+ }
86
+ else {
87
+ return "1:1";
88
+ }
89
+ };
90
+ export const movieGoogleAgent = async ({ namedInputs, params, config, }) => {
91
+ const { prompt, imagePath } = namedInputs;
92
+ const aspectRatio = getAspectRatio(params.canvasSize);
93
+ const model = params.model ?? "veo-2.0-generate-001"; // "veo-3.0-generate-preview";
94
+ const duration = params.duration ?? 8;
95
+ const projectId = config?.projectId;
96
+ const token = config?.token;
97
+ try {
98
+ const buffer = await generateMovie(projectId, model, token, prompt, imagePath, aspectRatio, duration);
99
+ if (buffer) {
100
+ return { buffer };
101
+ }
102
+ throw new Error("ERROR: geneateImage returned undefined");
103
+ }
104
+ catch (error) {
105
+ GraphAILogger.info("Failed to generate movie:", error.message);
106
+ throw error;
107
+ }
108
+ };
109
+ const movieGoogleAgentInfo = {
110
+ name: "movieGoogleAgent",
111
+ agent: movieGoogleAgent,
112
+ mock: movieGoogleAgent,
113
+ samples: [],
114
+ description: "Google Movie agent",
115
+ category: ["movie"],
116
+ author: "Receptron Team",
117
+ repository: "https://github.com/receptron/mulmocast-cli/",
118
+ // source: "https://github.com/receptron/mulmocast-cli/blob/main/src/agents/image_google_agent.ts",
119
+ license: "MIT",
120
+ environmentVariables: [],
121
+ };
122
+ export default movieGoogleAgentInfo;
@@ -0,0 +1,7 @@
1
+ import { AgentFunction, AgentFunctionInfo } from "graphai";
2
+ import { prompts } from "./prompts_data.js";
3
+ export declare const mulmoPromptsAgent: AgentFunction<{
4
+ promptKey: keyof typeof prompts;
5
+ }>;
6
+ declare const mulmoPromptsAgentInfo: AgentFunctionInfo;
7
+ export default mulmoPromptsAgentInfo;
@@ -0,0 +1,37 @@
1
+ import { prompts } from "./prompts_data.js";
2
+ export const mulmoPromptsAgent = async ({ params }) => {
3
+ const { promptKey } = params;
4
+ if (promptKey) {
5
+ const prompt = prompts[promptKey];
6
+ if (prompt) {
7
+ return {
8
+ text: prompt,
9
+ };
10
+ }
11
+ }
12
+ return prompts;
13
+ };
14
+ const mulmoPromptsAgentInfo = {
15
+ name: "mulmoPromptsAgent",
16
+ agent: mulmoPromptsAgent,
17
+ mock: mulmoPromptsAgent,
18
+ samples: [
19
+ {
20
+ inputs: {},
21
+ params: {
22
+ promptKey: "abstract",
23
+ },
24
+ result: {
25
+ text: "We need to add a summary at the beginning of script, which summarizes this episode, which is very engaging. Please come up with a few sentences for the announcer to read, enter them into this script, and present it as an artifact.",
26
+ },
27
+ },
28
+ ],
29
+ description: "Prompts Agent",
30
+ category: ["prompt"],
31
+ author: "Receptron team",
32
+ repository: "https://github.com/receptron/mulmocast-cli",
33
+ source: "https://github.com/receptron/mulmocast-cli/tree/main/src/agents/prompts_agent.ts",
34
+ // package: "@graphai/prompts",
35
+ license: "MIT",
36
+ };
37
+ export default mulmoPromptsAgentInfo;
@@ -0,0 +1,15 @@
1
+ export declare const prompts: {
2
+ abstract: string;
3
+ image_prompt: string;
4
+ prompt: string;
5
+ prompt2: string;
6
+ prompt3: string;
7
+ prompt_eng3: string;
8
+ prompt_seed: string;
9
+ prompt_seed_materials: string;
10
+ prompt_taro: string;
11
+ prompt_taro3_json: string;
12
+ prompt_taro3_json2: string;
13
+ prompt_taro_json: string;
14
+ summary: string;
15
+ };
@@ -0,0 +1,16 @@
1
+ // This file is auto-generated by src/tools/prompt.ts and Do not be edited manually.
2
+ export const prompts = {
3
+ abstract: "We need to add a summary at the beginning of script, which summarizes this episode, which is very engaging. Please come up with a few sentences for the announcer to read, enter them into this script, and present it as an artifact.",
4
+ image_prompt: 'We need to generate a series of images for this podcast. For each line of given json, generate an appropriate text prompt for text-2-image AI, considering the flow of whole discussion and add it as "imagePrompt" property to the script. We don\'t want to show student, teacher or classroom in the image. Do not eliminate any lines.\n\n[Examples]\nA modern tech conference stage with a speaker discussing AI advancements, futuristic lighting and a large digital screen displaying AI-related graphics.\nA close-up of an AI executive speaking at a press conference, with a backdrop displaying AI chip designs and a world map.\nA futuristic AI research lab with glowing blue data streams and a large AI model being visualized on a digital display.\nA high-tech meeting room with analysts discussing global AI trends, holographic charts displaying AI development.\nA balanced scale with AI progress on one side and economic factors on the other, symbolizing analysis and perspective.\nA newspaper headline about a breakthrough in AI technology, with digital code overlaying the article.\nA timeline showing the gradual evolution of AI models, with key milestones highlighted.\n',
5
+ prompt: 'generate a podcast script based on this topic in the JSON format using the opening statement below. Monologue by the Host. Complete story.\nClearly mention the news source.\nNews source:\nArticle url: ...\n\n```json\n{\n "title": "(title of this episode)",\n "description": "(short description of this episode)",\n "reference": "(url to the article)",\n "tts": "openAI", // or "nijivoice", default is "openAI"\n "speakers": {\n "Host": {\n "voiceId": "shimmer",\n "displayName": {\n "en": "Host"\n }\n },\n },\n "beats": [\n {\n "speaker": "Host",\n "text": "Hello and welcome to another episode of \'life is artificial\', where we explore the cutting edge of technology, innovation, and what the future could look like.",\n },\n {\n "speaker": "Host",\n "text": "Today, ...",\n },\n ...\n ]\n}\n```\n\n',
6
+ prompt2: 'generate a podcast interview script of Steve Jobs about Elon Musk and his achievements with Tesla and SpaceX, in the JSON format using the opening statement below. \n\n```json\n{\n title: "(title of this episode)",\n description: "(short description of this episode)",\n script:[\n {\n speaker: "Host",\n text: "Hello and welcome to another episode of \'life is artificial\', where we explore the cutting edge of technology, innovation, and what the future could look like.",\n },\n {\n speaker: "Host",\n text: "Today, ...",\n }\n ]\n}\n```\n\n',
7
+ prompt3: 'Turn this interview into a script in the follwing JSON format without remove any discussions between host and guest, but remove unnecessary text like advertisements. \n\n```json\n{\n "title": "(title of this episode)",\n "description": "(short description of this episode)",\n "script":[\n {\n "speaker": "Host",\n "text": "Hello, thank you for taking an interview from me.",\n },\n {\n "speaker": "Guest",\n "text": "You are welcome",\n }\n ]\n}\n```\n',
8
+ prompt_eng3: 'Please create a script as an artifact in the form of a conversation between a Student and a Teacher, with the goal of explaining everything about this topic in a way that even a middle schooler can understand. However, be sure to cover all the key points. The opening line should always start with an introduction by an Announcer, saying:\n"Welcome to another episode of Life is Beautiful by Satoshi Nakajima."\nBelow, I’ll provide an example on a different topic in JSON format. Please follow this format.\n\n{\n "title": "Martial Law in Korea and Its Impact on Japan",\n "description": "An insightful discussion about the recently declared martial law in Korea and its potential implications, including parallels with constitutional considerations in Japan.",\n "tts": "openAI",\n "voices": [\n "nova",\n "echo",\n "shimmer"\n ],\n "speakers": ["Announcer", "Student", "Teacher"],\n "script": [\n {\n "speaker": "Announcer",\n "text": "Welcome to another episode of Life is Beautiful by Satoshi Nakajima."\n },\n {\n "speaker": "Announcer",\n "text": "Today\'s topic is about the recently declared martial law in Korea."\n },\n {\n "speaker": "Student",\n "text": "Could you tell me about the martial law that was declared in Korea?"\n },\n {\n "speaker": "Teacher",\n "text": "Of course. Recently, the president in Korea suddenly declared what we call \'martial law.\'"\n },\n {\n "speaker": "Student",\n "text": "What is martial law?"\n },\n {\n "speaker": "Teacher",\n "text": "Simply put, it\'s a measure used to restrict people\'s freedoms using the military when the country is in an extremely dangerous situation. For example, they can prohibit political activities and control public gatherings."\n },\n {\n "speaker": "Student",\n "text": "That\'s scary. Why did they do that?"\n },\n {\n "speaker": "Teacher",\n "text": "While the president claimed it was because \'the National Assembly wasn\'t functioning properly,\' it appears he used it to protect his own position. The military then tried to enter the National Assembly and arrest the assembly members."\n },\n {\n "speaker": "Student",\n "text": "What!? Trying to arrest National Assembly members sounds really dangerous!"\n },\n {\n "speaker": "Teacher",\n "text": "That\'s right. If the military had occupied the National Assembly, they might not have been able to lift the martial law there. In other words, the president could have controlled the country as he wished indefinitely."\n },\n {\n "speaker": "Student",\n "text": "What happened in Korea?"\n },\n {\n "speaker": "Teacher",\n "text": "Fortunately, opposition party members and citizens quickly gathered to protest, and the martial law was lifted after six hours. But it was a close call - Korea\'s democracy could have been severely damaged."\n },\n {\n "speaker": "Student",\n "text": "That\'s serious... Could something like this happen in Japan?"\n },\n {\n "speaker": "Teacher",\n "text": "Actually, there\'s a similar discussion happening in Japan right now. The Liberal Democratic Party is trying to add an \'emergency declaration\' clause to the constitution."\n },\n {\n "speaker": "Student",\n "text": "Is the emergency declaration similar to Korea\'s martial law?"\n },\n {\n "speaker": "Teacher",\n "text": "There are similarities. For instance, if the Prime Minister claims there\'s a \'risk of social order disruption,\' they can use special powers to run the country. They can issue orders with the same force as laws and give directions to local governments."\n },\n {\n "speaker": "Student",\n "text": "That sounds convenient, but I\'m worried."\n },\n {\n "speaker": "Teacher",\n "text": "Yes, you\'re right. While it\'s useful to respond quickly in emergencies, it can be very dangerous if these powers are abused. For example, the Prime Minister might run the country in ways that benefit them or take away people\'s freedoms."\n },\n {\n "speaker": "Student",\n "text": "Could the military get involved in politics like in Korea?"\n },\n {\n "speaker": "Teacher",\n "text": "We can\'t completely rule it out, which is why we need to be careful. We citizens need to closely monitor whether the LDP\'s constitutional amendment proposal includes appropriate restrictions to prevent abuse of power and speak up. It\'s important for each of us to take an active interest in preventing damage to our democracy."\n }\n ]\n}',
9
+ prompt_seed: 'Please generate a podcast script based on the topic provided by the user.\nIf there are any unclear points, be sure to ask the user questions and clarify them before generating the script.\nThe output should follow the JSON format specified below.\n\n```json\n{\n "title": "(title of this episode)",\n "description": "(short description of this episode)",\n "reference": "(url to the article)",\n "tts": "openAI", // or "nijivoice", default is "openAI"\n "speakers": {\n "Host": {\n "voiceId": "shimmer",\n "displayName": {\n "en": "Host"\n }\n },\n },\n "beats": [\n {\n "speaker": "Host",\n "text": "Hello and welcome to another episode of \'life is artificial\', where we explore the cutting edge of technology, innovation, and what the future could look like.",\n },\n {\n "speaker": "Host",\n "text": "Today, ...",\n },\n ...\n ]\n}\n```\n\n',
10
+ prompt_seed_materials: 'Generate a podcast script based on the materials provided by the user. The script should follow the JSON format specified below.\n\n```json\n{\n "title": "(title of this episode)",\n "description": "(short description of this episode)",\n "reference": "(url to the article)",\n "tts": "openAI", // or "nijivoice", default is "openAI"\n "speechParams": {\n "speakers": {\n "Host": {\n "voiceId": "shimmer",\n "displayName": {\n "en": "Host"\n }\n }\n }\n },\n "beats": [\n {\n "speaker": "Host",\n "text": "Hello and welcome to another episode of \'life is artificial\', where we explore the cutting edge of technology, innovation, and what the future could look like.",\n },\n {\n "speaker": "Host",\n "text": "Today, ...",\n },\n ...\n ]\n}\n```\n',
11
+ prompt_taro: "この件について、内容全てを小学生にも分かるように、太郎くんと先生の会話、という形の台本にしてください。以下に別のトピックに関するサンプルを貼り付けます。\n\n太郎:先生、今日は原子炉の「冷温停止」について説明していただけますか?\n\n先生:もちろんだよ。でも同じ「冷温停止」でも言う人によって色々な意味があって、簡単じゃあないんだよ。\n\n太郎:そうなんですか。\n\n先生:もともとはね、「冷温停止」とは「制御棒を挿入して核反応を止めた後、冷却水を循環させて原子炉の温度を安定的に100度以下に保つ事」の意味なんだけどね、福島第一の場合はそうはいかないんだ。\n\n太郎:メルトダウンしてしまっているからですね。\n\n先生:そうなんだ、核燃料は本来なら燃料棒という形で原子炉の中に整然と並んでいるはずなんだが、福島第一の場合、それが熱で溶けて流れ落ちてしまった上に、その熱で原子炉にも、その外側にある格納容器にも穴が空いてしまっているんだ。\n\n太郎:じゃあ、いったいどうやってそれを安定して冷却するんですか?\n\n先生:それがとっても大変なんだよ。分かりやすくするために、トイレに例えてみよう。君のうちには水洗トイレがあるよね。\n\n太郎:もちろんです。ウォシュレットだって付いてます。\n\n先生:君のうちにあるトイレみたいに、使った後にはちゃんと汚いものを流してくれるトイレを「安定したトイレ」と呼ぶことにしよう。\n\n太郎:はい。\n\n先生:福島第一のトイレは、まず水を流すためのタンクがこわれちゃっているんだ。\n\n太郎:あの、トイレの上についている四角いタンクですね。\n\n先生:福島第一の場合、あのタンクが壊れているんで、仕方がなく洗面台からホースで水を引っ張って来て流しているんだ。\n\n太郎:ずいぶん不便ですね。\n\n先生:でも、問題はそれだけじゃなくて、便器も壊れて穴が空いちゃっているんだ。\n\n太郎:ええ、それじゃあ、トイレの床が水びたしじゃないですか。\n\n先生:そうだよ。それも水だけじゃなくて、便とか尿とかも穴から漏れているんだ。\n\n太郎:それはひどいですね。",
12
+ prompt_taro3_json: 'この件について、内容全てを中学生にも分かるように、太郎くん(Student)と先生(Teacher)の会話、という形の台本をArtifactとして作って。ただし要点はしっかりと押さえて。\n最初の一言は、Announcerによるトピックの紹介にし、常に、"米国で活躍するエンジニアが新しい技術やビジネスを分かりやすく解説する、中島聡のLife is beautiful。"でスタートして。\n以下に別のトピックに関するサンプルを貼り付けます。このJSONフォーマットに従って。\n\n{\n "title": "韓国の戒厳令とその日本への影響",\n "description": "韓国で最近発令された戒厳令とその可能性のある影響について、また日本の憲法に関する考慮事項との類似点を含めた洞察に満ちた議論。",\n "tts": "nijivoice",\n "voices": [\n "c05bf02d-bed2-4335-aa69-0798e9e85205",\n "b9277ce3-ba1c-4f6f-9a65-c05ca102ded0",\n "bc06c63f-fef6-43b6-92f7-67f919bd5dae"\n ],\n "speakers": ["Announcer", "Student", "Teacher"],\n "script": [\n {\n "speaker": "Announcer",\n "text": "米国で活躍するエンジニアが、新しい技術やビジネスを分かりやすく解説する、中島聡のLife is beautiful。今日は、韓国で最近発令された戒厳令についての解説です。"\n },\n {\n "speaker": "Student",\n "text": "先生、今日は韓国で起きた戒厳令のことを教えてもらえますか?"\n },\n {\n "speaker": "Teacher",\n "text": "もちろんだよ、太郎くん。韓国で最近、大統領が「戒厳令」っていうのを突然宣言したんだ。"\n },\n {\n "speaker": "Student",\n "text": "戒厳令ってなんですか?"\n },\n {\n "speaker": "Teacher",\n "text": "簡単に言うと、国がすごく危ない状態にあるとき、軍隊を使って人々の自由を制限するためのものなんだ。たとえば、政治活動を禁止したり、人の集まりを取り締まったりするんだよ。"\n },\n {\n "speaker": "Student",\n "text": "それって怖いですね。なんでそんなことをしたんですか?"\n },\n {\n "speaker": "Teacher",\n "text": "大統領は「国会がうまく機能していないから」と言っていたけど、実際には自分の立場を守るために使ったように見えるんだ。それで、軍隊が国会に突入して、議員たちを捕まえようとしたんだ。"\n },\n {\n "speaker": "Student",\n "text": "ええっ!?国会議員を捕まえようとするなんて、すごく危ないことじゃないですか。"\n },\n {\n "speaker": "Teacher",\n "text": "その通りだよ。もし軍隊が国会を占拠していたら、国会で戒厳令を解除することもできなかったかもしれない。つまり、大統領がずっと自分の好きなように国を支配できるようになってしまうんだ。"\n },\n {\n "speaker": "Student",\n "text": "韓国ではどうなったんですか?"\n },\n {\n "speaker": "Teacher",\n "text": "幸い、野党の議員や市民たちが急いで集まって抗議して、6時間後に戒厳令は解除されたんだ。でも、ほんの少しの違いで、韓国の民主主義が大きく傷つけられるところだったんだよ。"\n },\n {\n "speaker": "Student",\n "text": "それは大変なことですね…。日本ではそんなこと起きないんですか?"\n },\n {\n "speaker": "Teacher",\n "text": "実はね、今、日本でも似たような話があるんだよ。自民党が「緊急事態宣言」を憲法に追加しようとしているんだ。"\n },\n {\n "speaker": "Student",\n "text": "緊急事態宣言って、韓国の戒厳令と同じようなものなんですか?"\n },\n {\n "speaker": "Teacher",\n "text": "似ている部分があるね。たとえば、総理大臣が「社会秩序の混乱の危険があるから」と言えば、特別な権限を使って国を動かすことができるんだ。法律と同じ力を持つ命令を出したり、地方自治体に指示を出したりすることができるんだよ。"\n },\n {\n "speaker": "Student",\n "text": "それって便利そうですけど、なんだか心配です。"\n },\n {\n "speaker": "Teacher",\n "text": "そうだね。もちろん、緊急時には素早い対応が必要だから便利な面もあるけど、その権限が濫用されると、とても危険なんだ。たとえば、総理大臣が自分に都合のいいように国を動かしたり、国民の自由を奪ったりすることができるようになってしまうかもしれない。"\n },\n {\n "speaker": "Student",\n "text": "韓国みたいに、軍隊が政治に口を出してくることもあり得るんですか?"\n },\n {\n "speaker": "Teacher",\n "text": "完全にあり得ないとは言えないからこそ、注意が必要なんだ。私たち国民は、自民党の改憲案が権力の濫用を防ぐための適切な制限を含んでいるのかをしっかり監視し、声を上げることが求められる。民主主義が損なわれるのを防ぐために、私たち一人ひとりが積極的に関心を持つことが大切なんだよ。"\n },\n {\n "speaker": "Student",\n "text": "ありがとうございます。とても良い勉強になりました。"\n }\n ]\n}',
13
+ prompt_taro3_json2: 'この件について、内容全てを高校生にも分かるように、太郎くん(Student)と先生(Teacher)の会話、という形の台本をArtifactとして作って。ただし要点はしっかりと押さえて。\n以下に別のトピックに関するサンプルを貼り付けます。このJSONフォーマットに従って。\n\n{\n "title": "韓国の戒厳令とその日本への影響",\n "description": "韓国で最近発令された戒厳令とその可能性のある影響について、また日本の憲法に関する考慮事項との類似点を含めた洞察に満ちた議論。",\n "tts": "nijivoice",\n "voices": [\n "afd7df65-0fdc-4d31-ae8b-a29f0f5eed62",\n "a7619e48-bf6a-4f9f-843f-40485651257f",\n "bc06c63f-fef6-43b6-92f7-67f919bd5dae"\n ],\n "charactors": ["春玲", "森野颯太", "ベン・カーター"],\n "speakers": ["Announcer", "Student", "Teacher"],\n "script": [\n {\n "speaker": "Student",\n "text": "先生、今日は韓国で起きた戒厳令のことを教えてもらえますか?"\n },\n {\n "speaker": "Teacher",\n "text": "もちろんだよ、太郎くん。韓国で最近、大統領が「戒厳令」っていうのを突然宣言したんだ。"\n },\n {\n "speaker": "Student",\n "text": "戒厳令ってなんですか?"\n },\n {\n "speaker": "Teacher",\n "text": "簡単に言うと、国がすごく危ない状態にあるとき、軍隊を使って人々の自由を制限するためのものなんだ。たとえば、政治活動を禁止したり、人の集まりを取り締まったりするんだよ。"\n },\n {\n "speaker": "Student",\n "text": "それって怖いですね。なんでそんなことをしたんですか?"\n },\n {\n "speaker": "Teacher",\n "text": "大統領は「国会がうまく機能していないから」と言っていたけど、実際には自分の立場を守るために使ったように見えるんだ。それで、軍隊が国会に突入して、議員たちを捕まえようとしたんだ。"\n },\n {\n "speaker": "Student",\n "text": "ええっ!?国会議員を捕まえようとするなんて、すごく危ないことじゃないですか。"\n },\n {\n "speaker": "Teacher",\n "text": "その通りだよ。もし軍隊が国会を占拠していたら、国会で戒厳令を解除することもできなかったかもしれない。つまり、大統領がずっと自分の好きなように国を支配できるようになってしまうんだ。"\n },\n {\n "speaker": "Student",\n "text": "韓国ではどうなったんですか?"\n },\n {\n "speaker": "Teacher",\n "text": "幸い、野党の議員や市民たちが急いで集まって抗議して、6時間後に戒厳令は解除されたんだ。でも、ほんの少しの違いで、韓国の民主主義が大きく傷つけられるところだったんだよ。"\n },\n {\n "speaker": "Student",\n "text": "それは大変なことですね…。日本ではそんなこと起きないんですか?"\n },\n {\n "speaker": "Teacher",\n "text": "実はね、今、日本でも似たような話があるんだよ。自民党が「緊急事態宣言」を憲法に追加しようとしているんだ。"\n },\n {\n "speaker": "Student",\n "text": "緊急事態宣言って、韓国の戒厳令と同じようなものなんですか?"\n },\n {\n "speaker": "Teacher",\n "text": "似ている部分があるね。たとえば、総理大臣が「社会秩序の混乱の危険があるから」と言えば、特別な権限を使って国を動かすことができるんだ。法律と同じ力を持つ命令を出したり、地方自治体に指示を出したりすることができるんだよ。"\n },\n {\n "speaker": "Student",\n "text": "それって便利そうですけど、なんだか心配です。"\n },\n {\n "speaker": "Teacher",\n "text": "そうだね。もちろん、緊急時には素早い対応が必要だから便利な面もあるけど、その権限が濫用されると、とても危険なんだ。たとえば、総理大臣が自分に都合のいいように国を動かしたり、国民の自由を奪ったりすることができるようになってしまうかもしれない。"\n },\n {\n "speaker": "Student",\n "text": "韓国みたいに、軍隊が政治に口を出してくることもあり得るんですか?"\n },\n {\n "speaker": "Teacher",\n "text": "完全にあり得ないとは言えないからこそ、注意が必要なんだ。私たち国民は、自民党の改憲案が権力の濫用を防ぐための適切な制限を含んでいるのかをしっかり監視し、声を上げることが求められる。民主主義が損なわれるのを防ぐために、私たち一人ひとりが積極的に関心を持つことが大切なんだよ。"\n },\n {\n "speaker": "Student",\n "text": "ありがとうございます。とても良い勉強になりました。"\n },\n {\n "speaker": "Announcer",\n "text": "ご視聴、ありがとうございました。次回の放送もお楽しみに。"\n }\n ]\n}',
14
+ prompt_taro_json: 'この件について、内容全てを小学生にも分かるように、太郎くん(Guest)と先生(Host)の会話、という形の台本にしてください。以下に別のトピックに関するサンプルを貼り付けます。このJSONフォーマットに従ってください。\n\n{\n "title": "韓国の戒厳令とその日本への影響",\n "description": "韓国で最近発令された戒厳令とその可能性のある影響について、また日本の憲法に関する考慮事項との類似点を含めた洞察に満ちた議論。",\n "tts": "nijivoice",\n "script": [\n {\n "speaker": "Host",\n "text": "先生、今日は韓国で起きた戒厳令のことを教えてもらえますか?"\n },\n {\n "speaker": "Guest",\n "text": "もちろんだよ、太郎くん。韓国で最近、大統領が「戒厳令」っていうのを突然宣言したんだ。"\n },\n {\n "speaker": "Host",\n "text": "戒厳令ってなんですか?"\n },\n {\n "speaker": "Guest",\n "text": "簡単に言うと、国がすごく危ない状態にあるとき、軍隊を使って人々の自由を制限するためのものなんだ。たとえば、政治活動を禁止したり、人の集まりを取り締まったりするんだよ。"\n },\n {\n "speaker": "Host",\n "text": "それって怖いですね。なんでそんなことをしたんですか?"\n },\n {\n "speaker": "Guest",\n "text": "大統領は「国会がうまく機能していないから」と言っていたけど、実際には自分の立場を守るために使ったように見えるんだ。それで、軍隊が国会に突入して、議員たちを捕まえようとしたんだ。"\n },\n {\n "speaker": "Host",\n "text": "ええっ!?国会議員を捕まえようとするなんて、すごく危ないことじゃないですか。"\n },\n {\n "speaker": "Guest",\n "text": "その通りだよ。もし軍隊が国会を占拠していたら、国会で戒厳令を解除することもできなかったかもしれない。つまり、大統領がずっと自分の好きなように国を支配できるようになってしまうんだ。"\n },\n {\n "speaker": "Host",\n "text": "韓国ではどうなったんですか?"\n },\n {\n "speaker": "Guest",\n "text": "幸い、野党の議員や市民たちが急いで集まって抗議して、6時間後に戒厳令は解除されたんだ。でも、ほんの少しの違いで、韓国の民主主義が大きく傷つけられるところだったんだよ。"\n },\n {\n "speaker": "Host",\n "text": "それは大変なことですね…。日本ではそんなこと起きないんですか?"\n },\n {\n "speaker": "Guest",\n "text": "実はね、今、日本でも似たような話があるんだよ。自民党が「緊急事態宣言」を憲法に追加しようとしているんだ。"\n },\n {\n "speaker": "Host",\n "text": "緊急事態宣言って、韓国の戒厳令と同じようなものなんですか?"\n },\n {\n "speaker": "Guest",\n "text": "似ている部分があるね。たとえば、総理大臣が「社会秩序の混乱の危険があるから」と言えば、特別な権限を使って国を動かすことができるんだ。法律と同じ力を持つ命令を出したり、地方自治体に指示を出したりすることができるんだよ。"\n },\n {\n "speaker": "Host",\n "text": "それって便利そうですけど、なんだか心配です。"\n },\n {\n "speaker": "Guest",\n "text": "そうだね。もちろん、緊急時には素早い対応が必要だから便利な面もあるけど、その権限が濫用されると、とても危険なんだ。たとえば、総理大臣が自分に都合のいいように国を動かしたり、国民の自由を奪ったりすることができるようになってしまうかもしれない。"\n },\n {\n "speaker": "Host",\n "text": "韓国みたいに、軍隊が政治に口を出してくることもあり得るんですか?"\n },\n {\n "speaker": "Guest",\n "text": "完全にあり得ないとは言えないからこそ、注意が必要なんだ。私たち国民は、自民党の改憲案が権力の濫用を防ぐための適切な制限を含んでいるのかをしっかり監視し、声を上げることが求められる。民主主義が損なわれるのを防ぐために、私たち一人ひとりが積極的に関心を持つことが大切なんだよ。"\n }\n ]\n}',
15
+ summary: "We need to add a summary at the end of script, which summarizes this episode. Please come up with a few sentences for the announcer to read, enter them into this script, and present it as an artifact.",
16
+ };
@@ -0,0 +1,5 @@
1
+ import type { AgentFunction, AgentFunctionInfo } from "graphai";
2
+ import type { NijivoiceTTSAgentParams, AgentBufferResult, AgentTextInputs, AgentErrorResult, AgentConfig } from "../types/agent.js";
3
+ export declare const ttsNijivoiceAgent: AgentFunction<NijivoiceTTSAgentParams, AgentBufferResult | AgentErrorResult, AgentTextInputs, AgentConfig>;
4
+ declare const ttsNijivoiceAgentInfo: AgentFunctionInfo;
5
+ export default ttsNijivoiceAgentInfo;
@@ -0,0 +1,69 @@
1
+ import { GraphAILogger } from "graphai";
2
+ /*
3
+ const errorMessage = [
4
+ "TTS NijiVoice: No API key. ",
5
+ "You have the following options:",
6
+ "1. Obtain an API key from Niji Voice (https://platform.nijivoice.com/) and set it as the NIJIVOICE_API_KEY environment variable.",
7
+ '2. Use OpenAI\'s TTS instead of Niji Voice by changing speechParams.provider from "nijivoice" to "openai".',
8
+ ].join("\n");
9
+ */
10
+ export const ttsNijivoiceAgent = async ({ params, namedInputs, config, }) => {
11
+ const { suppressError, voice, speed, speed_global } = params;
12
+ const { apiKey } = config ?? {};
13
+ const { text } = namedInputs;
14
+ if (!apiKey) {
15
+ throw new Error("NijiVoice API key is required (NIJIVOICE_API_KEY)");
16
+ }
17
+ const url = `https://api.nijivoice.com/api/platform/v1/voice-actors/${voice}/generate-voice`;
18
+ const options = {
19
+ method: "POST",
20
+ headers: {
21
+ "x-api-key": apiKey,
22
+ accept: "application/json",
23
+ "content-type": "application/json",
24
+ },
25
+ body: JSON.stringify({
26
+ format: "mp3",
27
+ speed: String(speed ?? speed_global ?? "1.0"),
28
+ script: text,
29
+ }),
30
+ };
31
+ try {
32
+ const voiceRes = await fetch(url, options);
33
+ const voiceJson = await voiceRes.json();
34
+ if (voiceJson?.generatedVoice?.audioFileDownloadUrl) {
35
+ const audioRes = await fetch(voiceJson.generatedVoice.audioFileDownloadUrl);
36
+ const buffer = Buffer.from(await audioRes.arrayBuffer());
37
+ return { buffer };
38
+ }
39
+ if (suppressError) {
40
+ return {
41
+ error: voiceJson,
42
+ };
43
+ }
44
+ GraphAILogger.info(voiceJson);
45
+ throw new Error("TTS Nijivoice Error");
46
+ }
47
+ catch (e) {
48
+ if (suppressError) {
49
+ return {
50
+ error: e,
51
+ };
52
+ }
53
+ GraphAILogger.info(e);
54
+ throw new Error("TTS Nijivoice Error");
55
+ }
56
+ };
57
+ const ttsNijivoiceAgentInfo = {
58
+ name: "ttsNijivoiceAgent",
59
+ agent: ttsNijivoiceAgent,
60
+ mock: ttsNijivoiceAgent,
61
+ samples: [],
62
+ description: "TTS nijivoice agent",
63
+ category: ["tts"],
64
+ author: "Receptron Team",
65
+ repository: "https://github.com/receptron/mulmocast-cli/",
66
+ license: "MIT",
67
+ environmentVariables: ["NIJIVOICE_API_KEY"],
68
+ };
69
+ export default ttsNijivoiceAgentInfo;
@@ -0,0 +1,17 @@
1
+ import type { AgentFunction, AgentFunctionInfo, DefaultConfigData } from "graphai";
2
+ import { MulmoScript } from "../types/index.js";
3
+ interface ValidateMulmoScriptInputs {
4
+ text: string;
5
+ }
6
+ interface ValidateMulmoScriptResponse {
7
+ isValid: boolean;
8
+ data?: MulmoScript;
9
+ error?: string;
10
+ }
11
+ /**
12
+ * MulmoScript JSON validation agent
13
+ * Validates if a JSON string conforms to the MulmoScript schema
14
+ */
15
+ export declare const validateMulmoScriptAgent: AgentFunction<object, ValidateMulmoScriptResponse, ValidateMulmoScriptInputs, DefaultConfigData>;
16
+ declare const validateMulmoScriptAgentInfo: AgentFunctionInfo;
17
+ export default validateMulmoScriptAgentInfo;
@@ -0,0 +1,34 @@
1
+ import { mulmoScriptSchema } from "../types/schema.js";
2
+ /**
3
+ * MulmoScript JSON validation agent
4
+ * Validates if a JSON string conforms to the MulmoScript schema
5
+ */
6
+ export const validateMulmoScriptAgent = async ({ namedInputs, }) => {
7
+ const { text } = namedInputs;
8
+ try {
9
+ const jsonData = JSON.parse(text);
10
+ const parsed = mulmoScriptSchema.parse(jsonData);
11
+ return {
12
+ isValid: true,
13
+ data: parsed,
14
+ };
15
+ }
16
+ catch (error) {
17
+ return {
18
+ isValid: false,
19
+ error: error instanceof Error ? error.message : String(error),
20
+ };
21
+ }
22
+ };
23
+ const validateMulmoScriptAgentInfo = {
24
+ name: "validateMulmoScriptAgent",
25
+ agent: validateMulmoScriptAgent,
26
+ mock: validateMulmoScriptAgent,
27
+ samples: [],
28
+ description: "Validates if a JSON string conforms to the MulmoScript schema",
29
+ category: ["validation"],
30
+ author: "Receptron Team",
31
+ repository: "https://github.com/receptron/mulmocast-cli/tree/main/src/agents/validate_script_agent.ts",
32
+ license: "MIT",
33
+ };
34
+ export default validateMulmoScriptAgentInfo;
@@ -0,0 +1,15 @@
1
+ export declare const getArgs: () => {
2
+ [x: string]: unknown;
3
+ v: boolean;
4
+ o: string | undefined;
5
+ b: string | undefined;
6
+ l: string | undefined;
7
+ a: string | undefined;
8
+ i: string | undefined;
9
+ f: boolean;
10
+ c: string | undefined;
11
+ pdf_mode: string;
12
+ pdf_size: string;
13
+ _: (string | number)[];
14
+ $0: string;
15
+ };
@@ -0,0 +1,62 @@
1
+ import yargs from "yargs";
2
+ import { hideBin } from "yargs/helpers";
3
+ import { commonOptions } from "./common.js";
4
+ import { pdf_modes, pdf_sizes, languages } from "../utils/const.js";
5
+ export const getArgs = () => {
6
+ return commonOptions(yargs(hideBin(process.argv)))
7
+ .scriptName("mulmo")
8
+ .option("a", {
9
+ alias: "audiodir",
10
+ description: "audio dir",
11
+ demandOption: false,
12
+ type: "string",
13
+ })
14
+ .option("i", {
15
+ alias: "imagedir",
16
+ description: "image dir",
17
+ demandOption: false,
18
+ type: "string",
19
+ })
20
+ .option("f", {
21
+ alias: "force",
22
+ description: "force generate",
23
+ demandOption: false,
24
+ default: false,
25
+ type: "boolean",
26
+ })
27
+ .option("c", {
28
+ alias: "caption",
29
+ description: "Video captions",
30
+ choices: languages,
31
+ demandOption: false,
32
+ type: "string",
33
+ })
34
+ .option("pdf_mode", {
35
+ description: "pdf mode",
36
+ demandOption: false,
37
+ choices: pdf_modes,
38
+ type: "string",
39
+ default: "slide",
40
+ })
41
+ .option("pdf_size", {
42
+ choices: pdf_sizes,
43
+ default: "letter",
44
+ describe: "PDF paper size (default: letter for US standard)",
45
+ })
46
+ .command("$0 <action> <file>", "Run mulmocast", (yargs) => {
47
+ return yargs
48
+ .positional("action", {
49
+ describe: "action to perform",
50
+ choices: ["translate", "audio", "images", "movie", "pdf"],
51
+ type: "string",
52
+ })
53
+ .positional("file", {
54
+ describe: "Mulmo Script File",
55
+ type: "string",
56
+ });
57
+ })
58
+ .strict()
59
+ .help()
60
+ .alias("help", "h")
61
+ .parseSync();
62
+ };
package/lib/cli/bin.js CHANGED
File without changes
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import "dotenv/config";
3
+ export declare const getFileObject: (_args: {
4
+ [x: string]: unknown;
5
+ }) => {
6
+ baseDirPath: string;
7
+ mulmoFilePath: string;
8
+ mulmoFileDirPath: string;
9
+ outDirPath: string;
10
+ imageDirPath: string;
11
+ audioDirPath: string;
12
+ isHttpPath: boolean;
13
+ fileOrUrl: string;
14
+ outputStudioFilePath: string;
15
+ fileName: string;
16
+ };
17
+ export declare const main: () => Promise<void>;