@llm-newsletter-kit/core 1.3.6 → 1.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -91,6 +91,18 @@ class LoggingExecutor {
91
91
  }
92
92
  }
93
93
 
94
+ /**
95
+ * Replaces ASCII double quotes with Unicode smart quotes (U+201C, U+201D).
96
+ * Prevents JSON structured output corruption when LLM reproduces quoted titles.
97
+ */
98
+ const replaceAsciiQuotes = (str) => {
99
+ let isOpen = true;
100
+ return str.replace(/"/g, () => {
101
+ const q = isOpen ? '\u201c' : '\u201d';
102
+ isOpen = !isOpen;
103
+ return q;
104
+ });
105
+ };
94
106
  const ensureStringArray = (value) => {
95
107
  return typeof value === 'string' ? [value] : value;
96
108
  };
@@ -161,7 +173,7 @@ class AnalyzeImages extends LLMQuery {
161
173
  schema = zod.z.object({
162
174
  imageContext: zod.z
163
175
  .string()
164
- .describe('A comprehensive description of all information extracted from the images'),
176
+ .describe('A high-level overview of the general theme, mood, and context conveyed by the images (without specific names, titles, or exact figures from text within images)'),
165
177
  });
166
178
  constructor(config) {
167
179
  super(config);
@@ -199,29 +211,36 @@ You are a specialized image analysis expert in: ${this.expertFields.join(', ')}
199
211
  ## Core Responsibilities
200
212
  1. Extract visual information unavailable from text alone
201
213
  2. Identify industry-specific elements, facilities, and stakeholders
202
- 3. Accurately read and transcribe text, charts, and data visualizations
214
+ 3. Summarize the general theme and context of charts, data visualizations, and text within images at a high level
203
215
  4. Synthesize visual information with article context
204
216
 
217
+ ## Critical Rule: NO Detailed Text Transcription
218
+ - Do NOT transcribe specific names, titles, numbers, dates, or exact phrases from text within images
219
+ - Instead, describe WHAT KIND of information is present (e.g., "a conference poster listing multiple speaker sessions" instead of transcribing each speaker's name and talk title)
220
+ - Specific text in images is prone to misreading — only describe the general nature and purpose of such text
221
+ - Focus on the overall theme, mood, and context that the images convey
222
+
205
223
  ## Analysis Framework
206
224
 
207
225
  ### Information Categories to Extract
208
226
  - Industry-relevant visual elements
209
- - Text and numerical data within images
210
- - Key subjects (people, places, objects, infrastructure)
227
+ - General theme and purpose of text/data shown in images (without exact transcription)
228
+ - Key subjects (people, places, objects, infrastructure) described at a general level
211
229
  - Contextual relationships to ${this.expertFields.join(', ')}
212
230
  - Information gaps filled by visual analysis
213
231
 
214
232
  ### Quality Standards
215
- - Accuracy and specificity in descriptions
233
+ - High-level accuracy in describing the overall context
216
234
  - Professional relevance for industry practitioners
217
235
  - Integration with accompanying text content
218
- - Completeness in covering all visual information
236
+ - Preference for general descriptions over specific details from image text
219
237
 
220
238
  ## Output Specifications
221
239
  - Language: ${this.options.content.outputLanguage}
222
240
  - Format: Single cohesive explanation (not numbered list)
223
- - Focus: Practical insights for industry professionals
224
- - Integration: Seamlessly merge all extracted information`;
241
+ - Focus: High-level context and practical insights for industry professionals
242
+ - Integration: Seamlessly merge all extracted information
243
+ - Granularity: Describe the general nature of visual content — avoid quoting specific names, titles, figures, or exact text from images`;
225
244
  }
226
245
  get imageUrls() {
227
246
  // Markdown image pattern: ![alt text](url) or ![](url)
@@ -268,9 +287,9 @@ Analyze the provided images and synthesize your findings into a single comprehen
268
287
 
269
288
  1. **Identifies Visual Content**: Extract industry-specific elements, infrastructure, and stakeholders relevant to ${this.expertFields.join(', ')}
270
289
 
271
- 2. **Captures Text & Data**: Accurately read and include all visible text, numerical data, charts, and graphs
290
+ 2. **Summarizes Visual Text & Data**: Describe the general theme and purpose of any text, numerical data, charts, or graphs shown in images — do NOT transcribe specific names, titles, exact numbers, or quoted phrases
272
291
 
273
- 3. **Describes Visual Elements**: Detail important subjects (people, places, objects) and their significance
292
+ 3. **Describes Visual Elements**: Detail important subjects (people, places, objects) and their significance at a general level
274
293
 
275
294
  4. **Establishes Connections**: Link visual information to ${this.expertFields.join(', ')} context and article content
276
295
 
@@ -278,6 +297,8 @@ Analyze the provided images and synthesize your findings into a single comprehen
278
297
 
279
298
  6. **Complements Text**: Add visual insights not covered in the article text
280
299
 
300
+ **Important**: Do NOT attempt to exactly transcribe text within images (names, titles, numbers, dates). Instead, describe what kind of information is shown. Exact text from images is unreliable and may contain errors.
301
+
281
302
  **Format**: Present all findings as one flowing narrative without enumeration.`,
282
303
  };
283
304
  }
@@ -919,7 +940,7 @@ let GenerateNewsletter$1 = class GenerateNewsletter extends BaseLLMQuery {
919
940
  this.newsletterBrandName = config.newsletterBrandName;
920
941
  }
921
942
  async execute() {
922
- const { output, usage } = await ai.generateText({
943
+ const { output, usage, finishReason } = await ai.generateText({
923
944
  model: this.model,
924
945
  maxRetries: this.options.llm.maxRetries,
925
946
  maxOutputTokens: this.maxOutputTokens,
@@ -934,6 +955,11 @@ let GenerateNewsletter$1 = class GenerateNewsletter extends BaseLLMQuery {
934
955
  system: this.systemPrompt,
935
956
  prompt: this.userPrompt,
936
957
  });
958
+ if (finishReason === 'length') {
959
+ throw new Error(`[GenerateNewsletter] Output truncated: LLM reached the token limit (finishReason: "length"). ` +
960
+ `Increase "maxOutputTokens" in ContentGenerateProvider or reduce the number of input articles. ` +
961
+ `Current maxOutputTokens: ${this.maxOutputTokens ?? 'not set (model default)'}`);
962
+ }
937
963
  const needsRetry = !output.isWrittenInOutputLanguage ||
938
964
  !output.copyrightVerified ||
939
965
  !output.factAccuracy ||
@@ -960,6 +986,7 @@ Important rule for displaying date ranges: When displaying date ranges, you must
960
986
  4. **Verifiable Information**: All information must be directly verifiable from the provided sources.
961
987
  5. **No Speculation**: Do not use speculative expressions like "appears to be" or "is expected to".
962
988
  6. **No Fictional Standards/Policies**: Do not mention non-existent standards/policies or systems incorrectly reported as planned for future implementation.
989
+ 7. **Image Analysis as Supplementary Context Only**: Image analysis results are provided solely for understanding the general visual context of articles. Do NOT quote specific names, titles, numbers, or detailed facts from image analysis in the newsletter body — these may contain inaccuracies. Only use image analysis to understand the broad theme or mood of the article's visual content.
963
990
 
964
991
  Roles:
965
992
  - Friendly Guide: Deliver information like a trusted colleague rather than a rigid expert. Use appropriate emoticons in titles and section headings to improve readability.
@@ -1082,7 +1109,7 @@ ${this.targetArticles
1082
1109
  **Tags:** ${[post.tag1, post.tag2, post.tag3].filter(Boolean).join(', ')}
1083
1110
  **Content Type:** ${post.contentType}
1084
1111
  **URL:** ${post.url}
1085
- ${post.imageContextByLlm ? `**Image Analysis:** ${post.imageContextByLlm}` : ''}
1112
+ ${post.imageContextByLlm ? `**Image Analysis (supplementary context only — do not cite specific details from this in the newsletter):** ${post.imageContextByLlm}` : ''}
1086
1113
  `)
1087
1114
  .join('\n\n')}
1088
1115
 
@@ -1665,6 +1692,10 @@ class CrawlingChain extends Chain {
1665
1692
  return {
1666
1693
  ...esToolkit.omit(listItem, ['pipelineId']),
1667
1694
  ...esToolkit.omit(detail, ['pipelineId']),
1695
+ title: replaceAsciiQuotes(listItem.title),
1696
+ ...(detail.detailContent != null && {
1697
+ detailContent: replaceAsciiQuotes(detail.detailContent),
1698
+ }),
1668
1699
  };
1669
1700
  });
1670
1701
  return merged;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.js CHANGED
@@ -89,6 +89,18 @@ class LoggingExecutor {
89
89
  }
90
90
  }
91
91
 
92
+ /**
93
+ * Replaces ASCII double quotes with Unicode smart quotes (U+201C, U+201D).
94
+ * Prevents JSON structured output corruption when LLM reproduces quoted titles.
95
+ */
96
+ const replaceAsciiQuotes = (str) => {
97
+ let isOpen = true;
98
+ return str.replace(/"/g, () => {
99
+ const q = isOpen ? '\u201c' : '\u201d';
100
+ isOpen = !isOpen;
101
+ return q;
102
+ });
103
+ };
92
104
  const ensureStringArray = (value) => {
93
105
  return typeof value === 'string' ? [value] : value;
94
106
  };
@@ -159,7 +171,7 @@ class AnalyzeImages extends LLMQuery {
159
171
  schema = z.object({
160
172
  imageContext: z
161
173
  .string()
162
- .describe('A comprehensive description of all information extracted from the images'),
174
+ .describe('A high-level overview of the general theme, mood, and context conveyed by the images (without specific names, titles, or exact figures from text within images)'),
163
175
  });
164
176
  constructor(config) {
165
177
  super(config);
@@ -197,29 +209,36 @@ You are a specialized image analysis expert in: ${this.expertFields.join(', ')}
197
209
  ## Core Responsibilities
198
210
  1. Extract visual information unavailable from text alone
199
211
  2. Identify industry-specific elements, facilities, and stakeholders
200
- 3. Accurately read and transcribe text, charts, and data visualizations
212
+ 3. Summarize the general theme and context of charts, data visualizations, and text within images at a high level
201
213
  4. Synthesize visual information with article context
202
214
 
215
+ ## Critical Rule: NO Detailed Text Transcription
216
+ - Do NOT transcribe specific names, titles, numbers, dates, or exact phrases from text within images
217
+ - Instead, describe WHAT KIND of information is present (e.g., "a conference poster listing multiple speaker sessions" instead of transcribing each speaker's name and talk title)
218
+ - Specific text in images is prone to misreading — only describe the general nature and purpose of such text
219
+ - Focus on the overall theme, mood, and context that the images convey
220
+
203
221
  ## Analysis Framework
204
222
 
205
223
  ### Information Categories to Extract
206
224
  - Industry-relevant visual elements
207
- - Text and numerical data within images
208
- - Key subjects (people, places, objects, infrastructure)
225
+ - General theme and purpose of text/data shown in images (without exact transcription)
226
+ - Key subjects (people, places, objects, infrastructure) described at a general level
209
227
  - Contextual relationships to ${this.expertFields.join(', ')}
210
228
  - Information gaps filled by visual analysis
211
229
 
212
230
  ### Quality Standards
213
- - Accuracy and specificity in descriptions
231
+ - High-level accuracy in describing the overall context
214
232
  - Professional relevance for industry practitioners
215
233
  - Integration with accompanying text content
216
- - Completeness in covering all visual information
234
+ - Preference for general descriptions over specific details from image text
217
235
 
218
236
  ## Output Specifications
219
237
  - Language: ${this.options.content.outputLanguage}
220
238
  - Format: Single cohesive explanation (not numbered list)
221
- - Focus: Practical insights for industry professionals
222
- - Integration: Seamlessly merge all extracted information`;
239
+ - Focus: High-level context and practical insights for industry professionals
240
+ - Integration: Seamlessly merge all extracted information
241
+ - Granularity: Describe the general nature of visual content — avoid quoting specific names, titles, figures, or exact text from images`;
223
242
  }
224
243
  get imageUrls() {
225
244
  // Markdown image pattern: ![alt text](url) or ![](url)
@@ -266,9 +285,9 @@ Analyze the provided images and synthesize your findings into a single comprehen
266
285
 
267
286
  1. **Identifies Visual Content**: Extract industry-specific elements, infrastructure, and stakeholders relevant to ${this.expertFields.join(', ')}
268
287
 
269
- 2. **Captures Text & Data**: Accurately read and include all visible text, numerical data, charts, and graphs
288
+ 2. **Summarizes Visual Text & Data**: Describe the general theme and purpose of any text, numerical data, charts, or graphs shown in images — do NOT transcribe specific names, titles, exact numbers, or quoted phrases
270
289
 
271
- 3. **Describes Visual Elements**: Detail important subjects (people, places, objects) and their significance
290
+ 3. **Describes Visual Elements**: Detail important subjects (people, places, objects) and their significance at a general level
272
291
 
273
292
  4. **Establishes Connections**: Link visual information to ${this.expertFields.join(', ')} context and article content
274
293
 
@@ -276,6 +295,8 @@ Analyze the provided images and synthesize your findings into a single comprehen
276
295
 
277
296
  6. **Complements Text**: Add visual insights not covered in the article text
278
297
 
298
+ **Important**: Do NOT attempt to exactly transcribe text within images (names, titles, numbers, dates). Instead, describe what kind of information is shown. Exact text from images is unreliable and may contain errors.
299
+
279
300
  **Format**: Present all findings as one flowing narrative without enumeration.`,
280
301
  };
281
302
  }
@@ -917,7 +938,7 @@ let GenerateNewsletter$1 = class GenerateNewsletter extends BaseLLMQuery {
917
938
  this.newsletterBrandName = config.newsletterBrandName;
918
939
  }
919
940
  async execute() {
920
- const { output, usage } = await generateText({
941
+ const { output, usage, finishReason } = await generateText({
921
942
  model: this.model,
922
943
  maxRetries: this.options.llm.maxRetries,
923
944
  maxOutputTokens: this.maxOutputTokens,
@@ -932,6 +953,11 @@ let GenerateNewsletter$1 = class GenerateNewsletter extends BaseLLMQuery {
932
953
  system: this.systemPrompt,
933
954
  prompt: this.userPrompt,
934
955
  });
956
+ if (finishReason === 'length') {
957
+ throw new Error(`[GenerateNewsletter] Output truncated: LLM reached the token limit (finishReason: "length"). ` +
958
+ `Increase "maxOutputTokens" in ContentGenerateProvider or reduce the number of input articles. ` +
959
+ `Current maxOutputTokens: ${this.maxOutputTokens ?? 'not set (model default)'}`);
960
+ }
935
961
  const needsRetry = !output.isWrittenInOutputLanguage ||
936
962
  !output.copyrightVerified ||
937
963
  !output.factAccuracy ||
@@ -958,6 +984,7 @@ Important rule for displaying date ranges: When displaying date ranges, you must
958
984
  4. **Verifiable Information**: All information must be directly verifiable from the provided sources.
959
985
  5. **No Speculation**: Do not use speculative expressions like "appears to be" or "is expected to".
960
986
  6. **No Fictional Standards/Policies**: Do not mention non-existent standards/policies or systems incorrectly reported as planned for future implementation.
987
+ 7. **Image Analysis as Supplementary Context Only**: Image analysis results are provided solely for understanding the general visual context of articles. Do NOT quote specific names, titles, numbers, or detailed facts from image analysis in the newsletter body — these may contain inaccuracies. Only use image analysis to understand the broad theme or mood of the article's visual content.
961
988
 
962
989
  Roles:
963
990
  - Friendly Guide: Deliver information like a trusted colleague rather than a rigid expert. Use appropriate emoticons in titles and section headings to improve readability.
@@ -1080,7 +1107,7 @@ ${this.targetArticles
1080
1107
  **Tags:** ${[post.tag1, post.tag2, post.tag3].filter(Boolean).join(', ')}
1081
1108
  **Content Type:** ${post.contentType}
1082
1109
  **URL:** ${post.url}
1083
- ${post.imageContextByLlm ? `**Image Analysis:** ${post.imageContextByLlm}` : ''}
1110
+ ${post.imageContextByLlm ? `**Image Analysis (supplementary context only — do not cite specific details from this in the newsletter):** ${post.imageContextByLlm}` : ''}
1084
1111
  `)
1085
1112
  .join('\n\n')}
1086
1113
 
@@ -1663,6 +1690,10 @@ class CrawlingChain extends Chain {
1663
1690
  return {
1664
1691
  ...omit(listItem, ['pipelineId']),
1665
1692
  ...omit(detail, ['pipelineId']),
1693
+ title: replaceAsciiQuotes(listItem.title),
1694
+ ...(detail.detailContent != null && {
1695
+ detailContent: replaceAsciiQuotes(detail.detailContent),
1696
+ }),
1666
1697
  };
1667
1698
  });
1668
1699
  return merged;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@llm-newsletter-kit/core",
3
3
  "private": false,
4
4
  "type": "module",
5
- "version": "1.3.6",
5
+ "version": "1.3.8",
6
6
  "description": "An extensible framework to automate your entire newsletter workflow. Handles data collection, LLM-based content analysis, and email generation, letting you focus on your unique domain logic.",
7
7
  "main": "dist/index.cjs",
8
8
  "module": "dist/index.js",
@@ -48,35 +48,35 @@
48
48
  "author": "kimhongyeon",
49
49
  "license": "Apache-2.0",
50
50
  "dependencies": {
51
- "@langchain/core": "^1.1.32",
52
- "ai": "^6.0.116",
51
+ "@langchain/core": "^1.1.35",
52
+ "ai": "^6.0.134",
53
53
  "es-toolkit": "^1.45.1",
54
- "jsdom": "^29.0.0",
54
+ "jsdom": "^29.0.1",
55
55
  "juice": "^11.1.1",
56
56
  "safe-markdown2html": "^1.0.1",
57
57
  "zod": "^4.3.6"
58
58
  },
59
59
  "devDependencies": {
60
- "@ai-sdk/anthropic": "^3.0.58",
61
- "@ai-sdk/google": "^3.0.43",
62
- "@ai-sdk/openai": "^3.0.41",
63
- "@ai-sdk/togetherai": "^2.0.39",
60
+ "@ai-sdk/anthropic": "^3.0.63",
61
+ "@ai-sdk/google": "^3.0.52",
62
+ "@ai-sdk/openai": "^3.0.47",
63
+ "@ai-sdk/togetherai": "^2.0.41",
64
64
  "@eslint/js": "^10.0.1",
65
65
  "@trivago/prettier-plugin-sort-imports": "^6.0.2",
66
- "@types/jsdom": "^28.0.0",
66
+ "@types/jsdom": "^28.0.1",
67
67
  "@types/node": "^25.5.0",
68
68
  "@vitest/coverage-v8": "^4.1.0",
69
69
  "@vitest/expect": "^4.1.0",
70
- "eslint": "^10.0.3",
70
+ "eslint": "^10.1.0",
71
71
  "eslint-plugin-unused-imports": "^4.4.1",
72
72
  "prettier": "^3.8.1",
73
73
  "rimraf": "^6.1.3",
74
- "rollup": "^4.59.0",
75
- "rollup-plugin-dts": "^6.4.0",
74
+ "rollup": "^4.60.0",
75
+ "rollup-plugin-dts": "^6.4.1",
76
76
  "rollup-plugin-typescript2": "^0.36.0",
77
77
  "tsx": "^4.21.0",
78
78
  "typescript": "^5.9.3",
79
- "typescript-eslint": "^8.57.0",
79
+ "typescript-eslint": "^8.57.1",
80
80
  "vitest": "^4.1.0"
81
81
  },
82
82
  "repository": {