mulmocast 0.1.2 → 0.1.4

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 (60) hide show
  1. package/assets/templates/characters.json +16 -0
  2. package/assets/templates/html.json +6 -0
  3. package/lib/actions/audio.js +13 -19
  4. package/lib/actions/image_agents.d.ts +145 -0
  5. package/lib/actions/image_agents.js +59 -0
  6. package/lib/actions/image_references.d.ts +9 -0
  7. package/lib/actions/image_references.js +79 -0
  8. package/lib/actions/images.d.ts +17 -109
  9. package/lib/actions/images.js +83 -188
  10. package/lib/actions/index.d.ts +2 -0
  11. package/lib/actions/index.js +2 -0
  12. package/lib/actions/movie.js +3 -1
  13. package/lib/actions/pdf.js +5 -2
  14. package/lib/agents/image_google_agent.d.ts +2 -15
  15. package/lib/agents/image_google_agent.js +5 -5
  16. package/lib/agents/image_openai_agent.d.ts +2 -17
  17. package/lib/agents/image_openai_agent.js +9 -9
  18. package/lib/agents/movie_google_agent.d.ts +2 -17
  19. package/lib/agents/movie_google_agent.js +7 -7
  20. package/lib/agents/movie_replicate_agent.d.ts +2 -16
  21. package/lib/agents/movie_replicate_agent.js +4 -4
  22. package/lib/agents/tts_google_agent.d.ts +9 -1
  23. package/lib/agents/tts_google_agent.js +2 -2
  24. package/lib/agents/tts_nijivoice_agent.js +1 -1
  25. package/lib/agents/tts_openai_agent.d.ts +13 -1
  26. package/lib/agents/tts_openai_agent.js +2 -2
  27. package/lib/cli/helpers.js +7 -7
  28. package/lib/index.d.ts +1 -0
  29. package/lib/index.js +1 -0
  30. package/lib/methods/index.d.ts +1 -0
  31. package/lib/methods/index.js +1 -0
  32. package/lib/methods/mulmo_beat.d.ts +6 -0
  33. package/lib/methods/mulmo_beat.js +21 -0
  34. package/lib/methods/mulmo_presentation_style.d.ts +3 -1
  35. package/lib/methods/mulmo_presentation_style.js +31 -7
  36. package/lib/methods/mulmo_studio_context.js +3 -0
  37. package/lib/tools/story_to_script.js +2 -2
  38. package/lib/types/agent.d.ts +55 -0
  39. package/lib/types/agent.js +3 -0
  40. package/lib/types/schema.d.ts +560 -296
  41. package/lib/types/schema.js +19 -10
  42. package/lib/types/type.d.ts +3 -2
  43. package/lib/utils/const.d.ts +0 -1
  44. package/lib/utils/const.js +0 -1
  45. package/lib/utils/context.d.ts +24 -13
  46. package/lib/utils/context.js +1 -0
  47. package/lib/utils/ffmpeg_utils.d.ts +1 -1
  48. package/lib/utils/ffmpeg_utils.js +1 -1
  49. package/lib/utils/file.js +4 -4
  50. package/lib/utils/filters.js +3 -4
  51. package/lib/utils/markdown.js +1 -1
  52. package/lib/utils/preprocess.d.ts +15 -8
  53. package/lib/utils/provider2agent.d.ts +72 -0
  54. package/lib/utils/provider2agent.js +81 -0
  55. package/lib/utils/string.js +5 -5
  56. package/lib/utils/utils.d.ts +13 -11
  57. package/lib/utils/utils.js +56 -62
  58. package/package.json +7 -6
  59. package/scripts/templates/html.json +42 -0
  60. package/scripts/templates/image_refs.json +35 -0
@@ -1,16 +1,12 @@
1
- import { MulmoBeat, MulmoStudioMultiLingualData } from "../types/index.js";
2
1
  import type { ConfigDataDictionary, DefaultConfigData } from "graphai";
3
- export declare const llm: readonly ["openai", "anthropic", "gemini", "groq"];
4
- export type LLM = (typeof llm)[number];
5
- export declare const llmConfig: Record<LLM, {
6
- agent: string;
7
- defaultModel: string;
8
- max_tokens: number;
9
- }>;
2
+ import { MulmoBeat, MulmoStudioMultiLingualData } from "../types/index.js";
3
+ import { llm } from "./provider2agent.js";
4
+ import type { LLM } from "./provider2agent.js";
5
+ export { LLM, llm };
10
6
  export declare const llmPair: (_llm?: LLM, _model?: string) => {
11
- agent: string;
7
+ agent: "openAIAgent" | "anthropicAgent" | "geminiAgent" | "groqAgent";
12
8
  model: string;
13
- max_tokens: number;
9
+ max_tokens: 8192 | 4096;
14
10
  };
15
11
  export declare const chunkArray: <T>(array: T[], size?: number) => T[][];
16
12
  export declare const isHttp: (fileOrUrl: string) => boolean;
@@ -18,5 +14,11 @@ export declare const text2hash: (input: string) => string;
18
14
  export declare const localizedText: (beat: MulmoBeat, multiLingualData?: MulmoStudioMultiLingualData, lang?: string) => string;
19
15
  export declare const sleep: (milliseconds: number) => Promise<unknown>;
20
16
  export declare function userAssert(condition: boolean, message: string): asserts condition;
21
- export declare const settings2GraphAIConfig: (settings?: Record<string, string>) => ConfigDataDictionary<DefaultConfigData>;
17
+ export declare const settings2GraphAIConfig: (settings?: Record<string, string>, env?: Record<string, string | undefined>) => ConfigDataDictionary<DefaultConfigData>;
22
18
  export declare const getExtention: (contentType: string | null, url: string) => string;
19
+ type Primitive = string | number | boolean | symbol | bigint;
20
+ type CleanableValue = Primitive | null | undefined | CleanableObject | CleanableValue[];
21
+ type CleanableObject = {
22
+ [key: string]: CleanableValue;
23
+ };
24
+ export declare const deepClean: <T extends CleanableValue>(input: T) => T | undefined;
@@ -1,32 +1,11 @@
1
1
  import * as crypto from "crypto";
2
- export const llm = ["openai", "anthropic", "gemini", "groq"];
3
- export const llmConfig = {
4
- openai: {
5
- agent: "openAIAgent",
6
- defaultModel: "gpt-4o",
7
- max_tokens: 8192,
8
- },
9
- anthropic: {
10
- agent: "anthropicAgent",
11
- defaultModel: "claude-3-7-sonnet-20250219",
12
- max_tokens: 8192,
13
- },
14
- gemini: {
15
- agent: "geminiAgent",
16
- defaultModel: "gemini-1.5-flash",
17
- max_tokens: 8192,
18
- },
19
- groq: {
20
- agent: "groqAgent",
21
- defaultModel: "llama3-8b-8192",
22
- max_tokens: 4096,
23
- },
24
- };
2
+ import { provider2LLMAgent, llm } from "./provider2agent.js";
3
+ export { llm };
25
4
  export const llmPair = (_llm, _model) => {
26
5
  const llmKey = _llm ?? "openai";
27
- const agent = llmConfig[llmKey]?.agent ?? llmConfig.openai.agent;
28
- const model = _model ?? llmConfig[llmKey]?.defaultModel ?? llmConfig.openai.defaultModel;
29
- const max_tokens = llmConfig[llmKey]?.max_tokens ?? llmConfig.openai.max_tokens;
6
+ const agent = provider2LLMAgent[llmKey]?.agentName ?? provider2LLMAgent.openai.agentName;
7
+ const model = _model ?? provider2LLMAgent[llmKey]?.defaultModel ?? provider2LLMAgent.openai.defaultModel;
8
+ const max_tokens = provider2LLMAgent[llmKey]?.max_tokens ?? provider2LLMAgent.openai.max_tokens;
30
9
  return { agent, model, max_tokens };
31
10
  };
32
11
  export const chunkArray = (array, size = 3) => {
@@ -60,47 +39,42 @@ export function userAssert(condition, message) {
60
39
  throw new Error(message);
61
40
  }
62
41
  }
63
- export const settings2GraphAIConfig = (settings) => {
64
- const config = {};
65
- if (settings) {
66
- if (settings.OPENAI_API_KEY) {
67
- config.openAIAgent = {
68
- apiKey: settings.OPENAI_API_KEY,
69
- };
70
- config.ttsOpenaiAgent = {
71
- apiKey: settings.OPENAI_API_KEY,
72
- };
73
- config.imageOpenaiAgent = {
74
- apiKey: settings.OPENAI_API_KEY,
75
- };
76
- }
77
- if (settings.ANTHROPIC_API_TOKEN) {
78
- config.anthropicAgent = {
79
- apiKey: settings.ANTHROPIC_API_TOKEN,
80
- };
81
- }
82
- if (settings.REPLICATE_API_TOKEN) {
83
- config.movieReplicateAgent = {
84
- apiKey: settings.REPLICATE_API_TOKEN,
85
- };
86
- }
87
- if (settings.NIJIVOICE_API_KEY) {
88
- config.ttsNijivoiceAgent = {
89
- apiKey: settings.NIJIVOICE_API_KEY,
90
- };
91
- }
92
- if (settings.ELEVENLABS_API_KEY) {
93
- config.ttsElevenlabsAgent = {
94
- apiKey: settings.ELEVENLABS_API_KEY,
95
- };
96
- }
42
+ export const settings2GraphAIConfig = (settings, env) => {
43
+ const getKey = (prefix, key) => {
44
+ return settings?.[`${prefix}_${key}`] ?? settings?.[key] ?? env?.[`${prefix}_${key}`] ?? env?.[key];
45
+ };
46
+ const config = {
47
+ openAIAgent: {
48
+ apiKey: getKey("LLM", "OPENAI_API_KEY"),
49
+ baseURL: getKey("LLM", "OPENAI_BASE_URL"),
50
+ },
51
+ ttsOpenaiAgent: {
52
+ apiKey: getKey("TTS", "OPENAI_API_KEY"),
53
+ baseURL: getKey("TTS", "OPENAI_BASE_URL"),
54
+ },
55
+ imageOpenaiAgent: {
56
+ apiKey: getKey("IMAGE", "OPENAI_API_KEY"),
57
+ baseURL: getKey("IMAGE", "OPENAI_BASE_URL"),
58
+ },
59
+ anthropicAgent: {
60
+ apiKey: getKey("LLM", "ANTHROPIC_API_TOKEN"),
61
+ },
62
+ movieReplicateAgent: {
63
+ apiKey: getKey("MOVIE", "REPLICATE_API_TOKEN"),
64
+ },
65
+ ttsNijivoiceAgent: {
66
+ apiKey: getKey("TTS", "NIJIVOICE_API_KEY"),
67
+ },
68
+ ttsElevenlabsAgent: {
69
+ apiKey: getKey("TTS", "ELEVENLABS_API_KEY"),
70
+ },
97
71
  // TODO
98
72
  // browserlessAgent
99
73
  // ttsGoogleAgent
100
74
  // geminiAgent, groqAgent for tool
101
75
  // TAVILY_API_KEY ( for deep research)
102
- }
103
- return config;
76
+ };
77
+ return deepClean(config) ?? {};
104
78
  };
105
79
  export const getExtention = (contentType, url) => {
106
80
  if (contentType?.includes("jpeg") || contentType?.includes("jpg")) {
@@ -116,3 +90,23 @@ export const getExtention = (contentType, url) => {
116
90
  }
117
91
  return "png"; // default
118
92
  };
93
+ export const deepClean = (input) => {
94
+ if (input === null || input === undefined || input === "") {
95
+ return undefined;
96
+ }
97
+ if (Array.isArray(input)) {
98
+ const cleanedArray = input.map(deepClean).filter((v) => v !== undefined);
99
+ return cleanedArray.length > 0 ? cleanedArray : undefined;
100
+ }
101
+ if (typeof input === "object") {
102
+ const result = {};
103
+ for (const [key, value] of Object.entries(input)) {
104
+ const cleaned = deepClean(value);
105
+ if (cleaned !== undefined) {
106
+ result[key] = cleaned;
107
+ }
108
+ }
109
+ return Object.keys(result).length > 0 ? result : undefined;
110
+ }
111
+ return input;
112
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mulmocast",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -59,7 +59,7 @@
59
59
  },
60
60
  "homepage": "https://github.com/receptron/mulmocast-cli#readme",
61
61
  "dependencies": {
62
- "@google-cloud/text-to-speech": "^6.1.0",
62
+ "@google-cloud/text-to-speech": "^6.2.0",
63
63
  "@graphai/anthropic_agent": "^2.0.5",
64
64
  "@graphai/browserless_agent": "^2.0.1",
65
65
  "@graphai/gemini_agent": "^2.0.0",
@@ -69,18 +69,18 @@
69
69
  "@graphai/stream_agent_filter": "^2.0.2",
70
70
  "@graphai/vanilla": "^2.0.5",
71
71
  "@graphai/vanilla_node_agents": "^2.0.1",
72
- "@modelcontextprotocol/sdk": "^1.13.1",
72
+ "@modelcontextprotocol/sdk": "^1.15.1",
73
73
  "@tavily/core": "^0.5.9",
74
74
  "canvas": "^3.1.2",
75
75
  "clipboardy": "^4.0.0",
76
- "dotenv": "^17.1.0",
76
+ "dotenv": "^17.2.0",
77
77
  "fluent-ffmpeg": "^2.1.3",
78
78
  "google-auth-library": "^9.15.1",
79
79
  "graphai": "^2.0.12",
80
80
  "inquirer": "^12.7.0",
81
81
  "marked": "^16.0.0",
82
82
  "ora": "^8.2.0",
83
- "puppeteer": "^24.12.0",
83
+ "puppeteer": "^24.12.1",
84
84
  "replicate": "^1.0.1",
85
85
  "yaml": "^2.8.0",
86
86
  "yargs": "^18.0.0",
@@ -93,9 +93,10 @@
93
93
  "@receptron/test_utils": "^2.0.0",
94
94
  "@types/fluent-ffmpeg": "^2.1.26",
95
95
  "@types/yargs": "^17.0.33",
96
- "eslint": "^9.30.1",
96
+ "eslint": "^9.31.0",
97
97
  "eslint-config-prettier": "^10.1.5",
98
98
  "eslint-plugin-prettier": "^5.5.1",
99
+ "eslint-plugin-sonarjs": "^3.0.4",
99
100
  "prettier": "^3.6.2",
100
101
  "ts-node": "^10.9.2",
101
102
  "tsx": "^4.20.3",
@@ -0,0 +1,42 @@
1
+ {
2
+ "$mulmocast": {
3
+ "version": "1.0",
4
+ "credit": "closing"
5
+ },
6
+ "references": [
7
+ {
8
+ "url": "https://www.somegreatwebsite.com/article/123",
9
+ "title": "Title of the article we are referencing",
10
+ "type": "[TYPE OF ARTICLE: article, paper, image, video, audio]"
11
+ }
12
+ ],
13
+ "title": "[TITLE: Brief, engaging title for the topic]",
14
+ "htmlImageParams": {
15
+ "provider": "anthropic",
16
+ "model": "claude-3-7-sonnet-20250219"
17
+ },
18
+ "lang": "en",
19
+ "beats": [
20
+ {
21
+ "text": "[NARRATION: Narration for the beat.]",
22
+ "htmlPrompt": {
23
+ "prompt": "[PROMPT to create appropriate HTML page for the beat.]"
24
+ }
25
+ },
26
+ {
27
+ "text": "[NARRATION: Narration for the beat.]",
28
+ "htmlPrompt": {
29
+ "prompt": "[PROMPT to create appropriate HTML page for the beat with the data.]",
30
+ "data": {
31
+ "description": "DATA TO BE PRESENTED IN THIS BEAT (in any format)]",
32
+ "net_income": {
33
+ "Q2 FY2024": 320,
34
+ "Q3 FY2024": 333,
35
+ "Q4 FY2024": 350
36
+ },
37
+ "unit": "USD (Million)"
38
+ }
39
+ }
40
+ }
41
+ ]
42
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "$mulmocast": {
3
+ "version": "1.0"
4
+ },
5
+ "title": "[TITLE OF THE PRESENTAITON OR STORY]",
6
+ "imageParams": {
7
+ "images": {
8
+ "[CHARACTER_ID_1]": {
9
+ "type": "imagePrompt",
10
+ "prompt": "[IMAGE PROMPT FOR THIS CHARACTER]"
11
+ },
12
+ "[CHARACTER_ID_2]": {
13
+ "type": "imagePrompt",
14
+ "prompt": "[IMAGE PROMPT FOR THIS CHARACTER]"
15
+ }
16
+ }
17
+ },
18
+ "beats": [
19
+ {
20
+ "text": "[NARRATION FOR THIS BEAT]",
21
+ "imagePrompt": "[IMAGE PROMPT FOR THIS BEAT (with both characters)]",
22
+ "imageNames": ["[CHARACTER_ID_1]", "[CHARACTER_ID_2]"]
23
+ },
24
+ {
25
+ "text": "[NARRATION FOR THIS BEAT]",
26
+ "imagePrompt": "[IMAGE PROMPT FOR THIS BEAT (only character 1)]",
27
+ "imageNames": ["[CHARACTER_ID_1]"]
28
+ },
29
+ {
30
+ "text": "[NARRATION FOR THIS BEAT]",
31
+ "imagePrompt": "[IMAGE PROMPT FOR THIS BEAT (no character)]",
32
+ "imageNames": []
33
+ }
34
+ ]
35
+ }