mulmocast-preprocessor 0.5.2 → 0.5.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.
@@ -0,0 +1 @@
1
+ export { buildScriptContent, buildBeatContent, buildScriptMetaContent, scriptToViewerData, DEFAULT_INTERACTIVE_SYSTEM_PROMPT, } from "./core/ai/context-builder.js";
package/lib/context.js ADDED
@@ -0,0 +1,2 @@
1
+ // Lightweight entry point for context-building utilities (no GraphAI dependency)
2
+ export { buildScriptContent, buildBeatContent, buildScriptMetaContent, scriptToViewerData, DEFAULT_INTERACTIVE_SYSTEM_PROMPT, } from "./core/ai/context-builder.js";
@@ -12,10 +12,8 @@ export declare const getSystemPrompt: (options: QueryOptions) => string;
12
12
  * Build user prompt from script and question
13
13
  */
14
14
  export declare const buildUserPrompt: (script: ExtendedMulmoScript, question: string) => string;
15
- /**
16
- * Default system prompt for interactive query
17
- */
18
- export declare const DEFAULT_INTERACTIVE_SYSTEM_PROMPT = "You are answering questions based on the content provided.\n- Answer based ONLY on the information in the provided content\n- If the answer cannot be found in the content, say so clearly\n- Be concise and direct in your answers\n- Do not make up information that is not in the content\n- You may reference previous conversation when answering follow-up questions\n- If references are available and the user asks for more details, mention which reference could provide more information\n- When you suggest fetching a reference for more details, include [SUGGEST_FETCH: <url>] in your response";
15
+ import { DEFAULT_INTERACTIVE_SYSTEM_PROMPT } from "../../context-builder.js";
16
+ export { DEFAULT_INTERACTIVE_SYSTEM_PROMPT };
19
17
  /**
20
18
  * Default system prompt for interactive query with fetched content
21
19
  */
@@ -1,4 +1,4 @@
1
- import { getLanguageName, buildScriptContent } from "../../llm.js";
1
+ import { getLanguageName, buildScriptContent, scriptToViewerData } from "../../llm.js";
2
2
  /**
3
3
  * Default system prompt for query
4
4
  */
@@ -28,7 +28,7 @@ export const getSystemPrompt = (options) => {
28
28
  export const buildUserPrompt = (script, question) => {
29
29
  const parts = [];
30
30
  // Add common script content (title, language, sections with beats)
31
- parts.push(buildScriptContent(script));
31
+ parts.push(buildScriptContent(scriptToViewerData(script)));
32
32
  parts.push("---");
33
33
  parts.push("");
34
34
  parts.push(`Question: ${question}`);
@@ -36,17 +36,8 @@ export const buildUserPrompt = (script, question) => {
36
36
  parts.push("Answer:");
37
37
  return parts.join("\n");
38
38
  };
39
- /**
40
- * Default system prompt for interactive query
41
- */
42
- export const DEFAULT_INTERACTIVE_SYSTEM_PROMPT = `You are answering questions based on the content provided.
43
- - Answer based ONLY on the information in the provided content
44
- - If the answer cannot be found in the content, say so clearly
45
- - Be concise and direct in your answers
46
- - Do not make up information that is not in the content
47
- - You may reference previous conversation when answering follow-up questions
48
- - If references are available and the user asks for more details, mention which reference could provide more information
49
- - When you suggest fetching a reference for more details, include [SUGGEST_FETCH: <url>] in your response`;
39
+ import { DEFAULT_INTERACTIVE_SYSTEM_PROMPT } from "../../context-builder.js";
40
+ export { DEFAULT_INTERACTIVE_SYSTEM_PROMPT };
50
41
  /**
51
42
  * Default system prompt for interactive query with fetched content
52
43
  */
@@ -77,7 +68,7 @@ export const getInteractiveSystemPrompt = (options) => {
77
68
  export const buildInteractiveUserPrompt = (script, question, history) => {
78
69
  const parts = [];
79
70
  // Add common script content (title, language, sections with beats)
80
- parts.push(buildScriptContent(script));
71
+ parts.push(buildScriptContent(scriptToViewerData(script)));
81
72
  parts.push("---");
82
73
  parts.push("");
83
74
  // Add conversation history if exists
@@ -1,4 +1,4 @@
1
- import { getLanguageName, buildScriptContent } from "../../llm.js";
1
+ import { getLanguageName, buildScriptContent, scriptToViewerData } from "../../llm.js";
2
2
  /**
3
3
  * Default system prompt for text summary
4
4
  */
@@ -24,7 +24,7 @@ export const DEFAULT_SYSTEM_PROMPT_MARKDOWN = `You are creating a summary based
24
24
  export const buildUserPrompt = (script, options) => {
25
25
  const parts = [];
26
26
  // Add common script content (title, language, sections with beats)
27
- parts.push(buildScriptContent(script));
27
+ parts.push(buildScriptContent(scriptToViewerData(script)));
28
28
  // Add target length if specified
29
29
  if (options.targetLengthChars) {
30
30
  parts.push(`Target summary length: approximately ${options.targetLengthChars} characters`);
@@ -0,0 +1,21 @@
1
+ import type { ExtendedMulmoScript, ExtendedMulmoViewerData, ExtendedMulmoViewerBeat } from "@mulmocast/extended-types";
2
+ /**
3
+ * Default system prompt for interactive query
4
+ */
5
+ export declare const DEFAULT_INTERACTIVE_SYSTEM_PROMPT = "You are answering questions based on the content provided.\n- Answer based ONLY on the information in the provided content\n- If the answer cannot be found in the content, say so clearly\n- Be concise and direct in your answers\n- Do not make up information that is not in the content\n- You may reference previous conversation when answering follow-up questions\n- If references are available and the user asks for more details, mention which reference could provide more information\n- When you suggest fetching a reference for more details, include [SUGGEST_FETCH: <url>] in your response";
6
+ /**
7
+ * Build beat content including metadata
8
+ */
9
+ export declare const buildBeatContent: (beat: ExtendedMulmoViewerBeat, index: number) => string;
10
+ /**
11
+ * Build script-level metadata section
12
+ */
13
+ export declare const buildScriptMetaContent: (data: ExtendedMulmoViewerData) => string;
14
+ /**
15
+ * Convert ExtendedMulmoScript to ExtendedMulmoViewerData (extract only needed fields)
16
+ */
17
+ export declare const scriptToViewerData: (script: ExtendedMulmoScript) => ExtendedMulmoViewerData;
18
+ /**
19
+ * Build script content for user prompt (common part)
20
+ */
21
+ export declare const buildScriptContent: (data: ExtendedMulmoViewerData) => string;
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Default system prompt for interactive query
3
+ */
4
+ export const DEFAULT_INTERACTIVE_SYSTEM_PROMPT = `You are answering questions based on the content provided.
5
+ - Answer based ONLY on the information in the provided content
6
+ - If the answer cannot be found in the content, say so clearly
7
+ - Be concise and direct in your answers
8
+ - Do not make up information that is not in the content
9
+ - You may reference previous conversation when answering follow-up questions
10
+ - If references are available and the user asks for more details, mention which reference could provide more information
11
+ - When you suggest fetching a reference for more details, include [SUGGEST_FETCH: <url>] in your response`;
12
+ /**
13
+ * Build beat content including metadata
14
+ */
15
+ export const buildBeatContent = (beat, index) => {
16
+ const lines = [];
17
+ // Main text
18
+ const text = beat.text || "";
19
+ if (!text.trim())
20
+ return "";
21
+ lines.push(`[${index}] ${text}`);
22
+ // Add metadata if available
23
+ const meta = beat.meta;
24
+ if (meta) {
25
+ // Tags for categorization
26
+ if (meta.tags && meta.tags.length > 0) {
27
+ lines.push(` Tags: ${meta.tags.join(", ")}`);
28
+ }
29
+ // Context provides additional information not in the text
30
+ if (meta.context) {
31
+ lines.push(` Context: ${meta.context}`);
32
+ }
33
+ // Keywords highlight important terms
34
+ if (meta.keywords && meta.keywords.length > 0) {
35
+ lines.push(` Keywords: ${meta.keywords.join(", ")}`);
36
+ }
37
+ // Expected questions this beat can answer
38
+ if (meta.expectedQuestions && meta.expectedQuestions.length > 0) {
39
+ lines.push(` Can answer: ${meta.expectedQuestions.join("; ")}`);
40
+ }
41
+ }
42
+ return lines.join("\n");
43
+ };
44
+ /**
45
+ * Build script-level metadata section
46
+ */
47
+ export const buildScriptMetaContent = (data) => {
48
+ const meta = data.scriptMeta;
49
+ if (!meta)
50
+ return "";
51
+ const lines = [];
52
+ // Background info
53
+ if (meta.background) {
54
+ lines.push(`Background: ${meta.background}`);
55
+ }
56
+ // Audience and prerequisites
57
+ if (meta.audience) {
58
+ lines.push(`Target audience: ${meta.audience}`);
59
+ }
60
+ if (meta.prerequisites && meta.prerequisites.length > 0) {
61
+ lines.push(`Prerequisites: ${meta.prerequisites.join(", ")}`);
62
+ }
63
+ // Goals
64
+ if (meta.goals && meta.goals.length > 0) {
65
+ lines.push(`Goals: ${meta.goals.join("; ")}`);
66
+ }
67
+ // Keywords
68
+ if (meta.keywords && meta.keywords.length > 0) {
69
+ lines.push(`Keywords: ${meta.keywords.join(", ")}`);
70
+ }
71
+ // References
72
+ if (meta.references && meta.references.length > 0) {
73
+ lines.push("References:");
74
+ meta.references.forEach((ref) => {
75
+ const title = ref.title || ref.url;
76
+ const desc = ref.description ? ` - ${ref.description}` : "";
77
+ lines.push(` - [${ref.type || "web"}] ${title}: ${ref.url}${desc}`);
78
+ });
79
+ }
80
+ // FAQ
81
+ if (meta.faq && meta.faq.length > 0) {
82
+ lines.push("FAQ:");
83
+ meta.faq.forEach((faq) => {
84
+ lines.push(` Q: ${faq.question}`);
85
+ lines.push(` A: ${faq.answer}`);
86
+ });
87
+ }
88
+ // Author info
89
+ if (meta.author) {
90
+ lines.push(`Author: ${meta.author}`);
91
+ }
92
+ return lines.length > 0 ? lines.join("\n") : "";
93
+ };
94
+ /**
95
+ * Convert ExtendedMulmoScript to ExtendedMulmoViewerData (extract only needed fields)
96
+ */
97
+ export const scriptToViewerData = (script) => {
98
+ return {
99
+ beats: script.beats.map((b) => ({
100
+ text: b.text,
101
+ meta: b.meta,
102
+ variants: b.variants,
103
+ id: b.id,
104
+ })),
105
+ title: script.title,
106
+ lang: script.lang,
107
+ scriptMeta: script.scriptMeta,
108
+ outputProfiles: script.outputProfiles,
109
+ };
110
+ };
111
+ /**
112
+ * Build script content for user prompt (common part)
113
+ */
114
+ export const buildScriptContent = (data) => {
115
+ const parts = [];
116
+ // Add script title and language
117
+ parts.push(`# Script: ${data.title}`);
118
+ parts.push(`Language: ${data.lang}`);
119
+ parts.push("");
120
+ // Add script-level metadata
121
+ const scriptMetaContent = buildScriptMetaContent(data);
122
+ if (scriptMetaContent) {
123
+ parts.push("## About this content");
124
+ parts.push(scriptMetaContent);
125
+ parts.push("");
126
+ }
127
+ // Collect all content from beats grouped by section
128
+ const sections = new Map();
129
+ data.beats.forEach((beat, index) => {
130
+ const content = buildBeatContent(beat, index);
131
+ if (!content)
132
+ return;
133
+ const section = beat.meta?.section || "main";
134
+ if (!sections.has(section)) {
135
+ sections.set(section, []);
136
+ }
137
+ sections.get(section).push(content);
138
+ });
139
+ // Output by section
140
+ sections.forEach((contents, section) => {
141
+ parts.push(`## Section: ${section}`);
142
+ contents.forEach((c) => parts.push(c));
143
+ parts.push("");
144
+ });
145
+ return parts.join("\n");
146
+ };
@@ -1,5 +1,6 @@
1
1
  import type { ExtendedMulmoScript } from "@mulmocast/extended-types";
2
2
  import type { LLMProvider } from "../../types/summarize.js";
3
+ export { buildBeatContent, buildScriptMetaContent, buildScriptContent, scriptToViewerData } from "./context-builder.js";
3
4
  /**
4
5
  * Base options for LLM operations
5
6
  */
@@ -39,10 +40,6 @@ export declare const filterScript: (script: ExtendedMulmoScript, options: BaseLL
39
40
  * Get language name from code
40
41
  */
41
42
  export declare const getLanguageName: (langCode: string) => string;
42
- /**
43
- * Build script content for user prompt (common part)
44
- */
45
- export declare const buildScriptContent: (script: ExtendedMulmoScript) => string;
46
43
  /**
47
44
  * Command execution result
48
45
  */
@@ -6,6 +6,8 @@ import { anthropicAgent } from "@graphai/anthropic_agent";
6
6
  import { groqAgent } from "@graphai/groq_agent";
7
7
  import { geminiAgent } from "@graphai/gemini_agent";
8
8
  import { filterBySection, filterByTags } from "../preprocessing/filter.js";
9
+ // Re-export pure context-building functions (no GraphAI dependency)
10
+ export { buildBeatContent, buildScriptMetaContent, buildScriptContent, scriptToViewerData } from "./context-builder.js";
9
11
  dotenv.config({ quiet: true });
10
12
  const agents = vanillaAgents.default ?? vanillaAgents;
11
13
  const provider2Agent = {
@@ -103,124 +105,6 @@ export const getLanguageName = (langCode) => {
103
105
  };
104
106
  return langMap[langCode] || langCode;
105
107
  };
106
- /**
107
- * Build beat content including metadata
108
- */
109
- const buildBeatContent = (beat, index) => {
110
- const lines = [];
111
- // Main text
112
- const text = beat.text || "";
113
- if (!text.trim())
114
- return "";
115
- lines.push(`[${index}] ${text}`);
116
- // Add metadata if available
117
- const meta = beat.meta;
118
- if (meta) {
119
- // Tags for categorization
120
- if (meta.tags && meta.tags.length > 0) {
121
- lines.push(` Tags: ${meta.tags.join(", ")}`);
122
- }
123
- // Context provides additional information not in the text
124
- if (meta.context) {
125
- lines.push(` Context: ${meta.context}`);
126
- }
127
- // Keywords highlight important terms
128
- if (meta.keywords && meta.keywords.length > 0) {
129
- lines.push(` Keywords: ${meta.keywords.join(", ")}`);
130
- }
131
- // Expected questions this beat can answer
132
- if (meta.expectedQuestions && meta.expectedQuestions.length > 0) {
133
- lines.push(` Can answer: ${meta.expectedQuestions.join("; ")}`);
134
- }
135
- }
136
- return lines.join("\n");
137
- };
138
- /**
139
- * Build script-level metadata section
140
- */
141
- const buildScriptMetaContent = (script) => {
142
- const meta = script.scriptMeta;
143
- if (!meta)
144
- return "";
145
- const lines = [];
146
- // Background info
147
- if (meta.background) {
148
- lines.push(`Background: ${meta.background}`);
149
- }
150
- // Audience and prerequisites
151
- if (meta.audience) {
152
- lines.push(`Target audience: ${meta.audience}`);
153
- }
154
- if (meta.prerequisites && meta.prerequisites.length > 0) {
155
- lines.push(`Prerequisites: ${meta.prerequisites.join(", ")}`);
156
- }
157
- // Goals
158
- if (meta.goals && meta.goals.length > 0) {
159
- lines.push(`Goals: ${meta.goals.join("; ")}`);
160
- }
161
- // Keywords
162
- if (meta.keywords && meta.keywords.length > 0) {
163
- lines.push(`Keywords: ${meta.keywords.join(", ")}`);
164
- }
165
- // References
166
- if (meta.references && meta.references.length > 0) {
167
- lines.push("References:");
168
- meta.references.forEach((ref) => {
169
- const title = ref.title || ref.url;
170
- const desc = ref.description ? ` - ${ref.description}` : "";
171
- lines.push(` - [${ref.type || "web"}] ${title}: ${ref.url}${desc}`);
172
- });
173
- }
174
- // FAQ
175
- if (meta.faq && meta.faq.length > 0) {
176
- lines.push("FAQ:");
177
- meta.faq.forEach((faq) => {
178
- lines.push(` Q: ${faq.question}`);
179
- lines.push(` A: ${faq.answer}`);
180
- });
181
- }
182
- // Author info
183
- if (meta.author) {
184
- lines.push(`Author: ${meta.author}`);
185
- }
186
- return lines.length > 0 ? lines.join("\n") : "";
187
- };
188
- /**
189
- * Build script content for user prompt (common part)
190
- */
191
- export const buildScriptContent = (script) => {
192
- const parts = [];
193
- // Add script title and language
194
- parts.push(`# Script: ${script.title}`);
195
- parts.push(`Language: ${script.lang}`);
196
- parts.push("");
197
- // Add script-level metadata
198
- const scriptMetaContent = buildScriptMetaContent(script);
199
- if (scriptMetaContent) {
200
- parts.push("## About this content");
201
- parts.push(scriptMetaContent);
202
- parts.push("");
203
- }
204
- // Collect all content from beats grouped by section
205
- const sections = new Map();
206
- script.beats.forEach((beat, index) => {
207
- const content = buildBeatContent(beat, index);
208
- if (!content)
209
- return;
210
- const section = beat.meta?.section || "main";
211
- if (!sections.has(section)) {
212
- sections.set(section, []);
213
- }
214
- sections.get(section).push(content);
215
- });
216
- // Output by section
217
- sections.forEach((contents, section) => {
218
- parts.push(`## Section: ${section}`);
219
- contents.forEach((c) => parts.push(c));
220
- parts.push("");
221
- });
222
- return parts.join("\n");
223
- };
224
108
  /**
225
109
  * Execute a command (summarize, query, etc.) with common logic
226
110
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mulmocast-preprocessor",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Preprocessor for MulmoScript",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -12,6 +12,10 @@
12
12
  ".": {
13
13
  "types": "./lib/index.d.ts",
14
14
  "default": "./lib/index.js"
15
+ },
16
+ "./context": {
17
+ "types": "./lib/context.d.ts",
18
+ "default": "./lib/context.js"
15
19
  }
16
20
  },
17
21
  "files": [