@llm-newsletter-kit/core 2.1.0 → 3.0.1
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/README.md +6 -16
- package/dist/index.js +10 -9
- package/dist/index.js.map +1 -1
- package/package.json +22 -20
- package/dist/index.cjs +0 -2047
- package/dist/index.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ A type‑first, extensible toolkit that automates LLM‑based newsletter creatio
|
|
|
21
21
|
- Type-first design (TypeScript, ESM) with strong contracts
|
|
22
22
|
- Flexible dependency injection: easily swap Crawling/Analysis/ContentGenerate/Task/Logging/Email
|
|
23
23
|
- Operational features built-in: retries, chain options, preview email sending, etc.
|
|
24
|
-
- Rollup build (ESM+
|
|
24
|
+
- Rollup build (ESM+d.ts), Vitest 100% coverage, GitHub Actions CI included
|
|
25
25
|
|
|
26
26
|
## Project Background
|
|
27
27
|
|
|
@@ -101,12 +101,8 @@ const config: GenerateNewsletterConfig<string> = {
|
|
|
101
101
|
},
|
|
102
102
|
crawlingProvider: {
|
|
103
103
|
// customFetch: myProxyFetch, // Optional: custom fetch for proxy support
|
|
104
|
-
crawlingTargetGroups: [
|
|
105
|
-
|
|
106
|
-
],
|
|
107
|
-
fetchExistingArticlesByUrls: async (urls) => [
|
|
108
|
-
/* ... */
|
|
109
|
-
],
|
|
104
|
+
crawlingTargetGroups: [/* ... */],
|
|
105
|
+
fetchExistingArticlesByUrls: async (urls) => [/* ... */],
|
|
110
106
|
saveCrawledArticles: async (articles, context) => articles.length,
|
|
111
107
|
},
|
|
112
108
|
analysisProvider: {
|
|
@@ -114,12 +110,8 @@ const config: GenerateNewsletterConfig<string> = {
|
|
|
114
110
|
classifyTagOptions: { model: openai('gpt-5-mini') },
|
|
115
111
|
analyzeImagesOptions: { model: openai('gpt-5.1') },
|
|
116
112
|
determineScoreOptions: { model: openai('gpt-5.1') },
|
|
117
|
-
fetchUnscoredArticles: async () => [
|
|
118
|
-
|
|
119
|
-
],
|
|
120
|
-
fetchTags: async () => [
|
|
121
|
-
/* ... */
|
|
122
|
-
],
|
|
113
|
+
fetchUnscoredArticles: async () => [/* ... */],
|
|
114
|
+
fetchTags: async () => [/* ... */],
|
|
123
115
|
update: async (article) => {},
|
|
124
116
|
},
|
|
125
117
|
contentGenerateProvider: {
|
|
@@ -128,9 +120,7 @@ const config: GenerateNewsletterConfig<string> = {
|
|
|
128
120
|
issueOrder: 1,
|
|
129
121
|
newsletterBrandName: 'Tech Insight Weekly',
|
|
130
122
|
publicationCriteria: { minimumArticleCountForIssue: 5 },
|
|
131
|
-
fetchArticleCandidates: async () => [
|
|
132
|
-
/* ... */
|
|
133
|
-
],
|
|
123
|
+
fetchArticleCandidates: async () => [/* ... */],
|
|
134
124
|
htmlTemplate: ({ content }) => `<html>...</html>`,
|
|
135
125
|
saveNewsletter: async ({ newsletter }) => ({ id: 1 }),
|
|
136
126
|
},
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { pick, omit } from 'es-toolkit';
|
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { generateText, Output } from 'ai';
|
|
5
5
|
import { JSDOM } from 'jsdom';
|
|
6
|
+
import juice from 'juice';
|
|
6
7
|
import safeMarkdown2Html from 'safe-markdown2html';
|
|
7
8
|
import { randomUUID } from 'node:crypto';
|
|
8
9
|
|
|
@@ -208,7 +209,7 @@ class AnalyzeImages extends LLMQuery {
|
|
|
208
209
|
model: this.model,
|
|
209
210
|
maxRetries: this.options.llm.maxRetries,
|
|
210
211
|
schema: this.schema,
|
|
211
|
-
|
|
212
|
+
instructions: this.systemPrompt,
|
|
212
213
|
messages: [
|
|
213
214
|
{
|
|
214
215
|
role: 'user',
|
|
@@ -294,8 +295,9 @@ You are a specialized image analysis expert in: ${this.expertFields.join(', ')}
|
|
|
294
295
|
}
|
|
295
296
|
get imageMessages() {
|
|
296
297
|
return this.imageUrls.map((url) => ({
|
|
297
|
-
type: '
|
|
298
|
-
|
|
298
|
+
type: 'file',
|
|
299
|
+
mediaType: 'image',
|
|
300
|
+
data: url,
|
|
299
301
|
}));
|
|
300
302
|
}
|
|
301
303
|
get textMessage() {
|
|
@@ -354,7 +356,7 @@ class ClassifyTags extends LLMQuery {
|
|
|
354
356
|
model: this.model,
|
|
355
357
|
maxRetries: this.options.llm.maxRetries,
|
|
356
358
|
schema: this.schema,
|
|
357
|
-
|
|
359
|
+
instructions: this.systemPrompt,
|
|
358
360
|
prompt: this.userPrompt,
|
|
359
361
|
});
|
|
360
362
|
return { result: output, usage };
|
|
@@ -450,7 +452,7 @@ class DetermineArticleImportance extends LLMQuery {
|
|
|
450
452
|
model: this.model,
|
|
451
453
|
maxRetries: this.options.llm.maxRetries,
|
|
452
454
|
schema: this.schema,
|
|
453
|
-
|
|
455
|
+
instructions: this.systemPrompt,
|
|
454
456
|
prompt: this.userPrompt,
|
|
455
457
|
});
|
|
456
458
|
return { result: output.importanceScore, usage };
|
|
@@ -1035,7 +1037,7 @@ let GenerateNewsletter$1 = class GenerateNewsletter extends BaseLLMQuery {
|
|
|
1035
1037
|
presencePenalty: this.presencePenalty,
|
|
1036
1038
|
frequencyPenalty: this.frequencyPenalty,
|
|
1037
1039
|
schema: this.schema,
|
|
1038
|
-
|
|
1040
|
+
instructions: this.systemPrompt,
|
|
1039
1041
|
prompt: this.userPrompt,
|
|
1040
1042
|
});
|
|
1041
1043
|
if (finishReason === 'length') {
|
|
@@ -1274,8 +1276,7 @@ function addUsage(a, b) {
|
|
|
1274
1276
|
};
|
|
1275
1277
|
}
|
|
1276
1278
|
|
|
1277
|
-
|
|
1278
|
-
const { default: juice } = await import('juice');
|
|
1279
|
+
function inlineCss(html) {
|
|
1279
1280
|
return juice(html);
|
|
1280
1281
|
}
|
|
1281
1282
|
class ContentGenerateChain extends Chain {
|
|
@@ -1410,7 +1411,7 @@ class ContentGenerateChain extends Chain {
|
|
|
1410
1411
|
const { id } = await this.provider.saveNewsletter({
|
|
1411
1412
|
newsletter: {
|
|
1412
1413
|
...coreContent,
|
|
1413
|
-
htmlBody:
|
|
1414
|
+
htmlBody: inlineCss(html),
|
|
1414
1415
|
issueOrder: this.provider.issueOrder,
|
|
1415
1416
|
date: this.dateService.getPublicationISODateString(),
|
|
1416
1417
|
},
|
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,16 +2,14 @@
|
|
|
2
2
|
"name": "@llm-newsletter-kit/core",
|
|
3
3
|
"private": false,
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "3.0.1",
|
|
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
|
-
"main": "dist/index.
|
|
8
|
-
"module": "dist/index.js",
|
|
7
|
+
"main": "dist/index.js",
|
|
9
8
|
"types": "dist/index.d.ts",
|
|
10
9
|
"exports": {
|
|
11
10
|
".": {
|
|
12
11
|
"types": "./dist/index.d.ts",
|
|
13
12
|
"import": "./dist/index.js",
|
|
14
|
-
"require": "./dist/index.cjs",
|
|
15
13
|
"default": "./dist/index.js"
|
|
16
14
|
}
|
|
17
15
|
},
|
|
@@ -49,36 +47,36 @@
|
|
|
49
47
|
"author": "kimhongyeon",
|
|
50
48
|
"license": "Apache-2.0",
|
|
51
49
|
"dependencies": {
|
|
52
|
-
"@langchain/core": "^1.2.
|
|
53
|
-
"ai": "^
|
|
54
|
-
"es-toolkit": "^1.
|
|
50
|
+
"@langchain/core": "^1.2.3",
|
|
51
|
+
"ai": "^7.0.37",
|
|
52
|
+
"es-toolkit": "^1.50.0",
|
|
55
53
|
"jsdom": "^29.1.1",
|
|
56
54
|
"juice": "^12.1.1",
|
|
57
|
-
"safe-markdown2html": "^1.0.
|
|
55
|
+
"safe-markdown2html": "^1.0.9",
|
|
58
56
|
"zod": "^4.4.3"
|
|
59
57
|
},
|
|
60
58
|
"devDependencies": {
|
|
61
|
-
"@ai-sdk/anthropic": "^
|
|
62
|
-
"@ai-sdk/google": "^
|
|
63
|
-
"@ai-sdk/openai": "^
|
|
64
|
-
"@ai-sdk/togetherai": "^
|
|
59
|
+
"@ai-sdk/anthropic": "^4.0.20",
|
|
60
|
+
"@ai-sdk/google": "^4.0.24",
|
|
61
|
+
"@ai-sdk/openai": "^4.0.20",
|
|
62
|
+
"@ai-sdk/togetherai": "^3.0.15",
|
|
65
63
|
"@eslint/js": "^10.0.1",
|
|
66
64
|
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
|
|
67
65
|
"@types/jsdom": "^28.0.3",
|
|
68
|
-
"@types/node": "^26.
|
|
69
|
-
"@vitest/coverage-v8": "^4.1.
|
|
70
|
-
"@vitest/expect": "^4.1.
|
|
71
|
-
"eslint": "^10.
|
|
66
|
+
"@types/node": "^26.1.1",
|
|
67
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
68
|
+
"@vitest/expect": "^4.1.10",
|
|
69
|
+
"eslint": "^10.8.0",
|
|
72
70
|
"eslint-plugin-unused-imports": "^4.4.1",
|
|
73
|
-
"prettier": "^3.
|
|
71
|
+
"prettier": "^3.9.6",
|
|
74
72
|
"rimraf": "^6.1.3",
|
|
75
73
|
"rollup": "^4.62.2",
|
|
76
74
|
"rollup-plugin-dts": "^6.4.1",
|
|
77
75
|
"rollup-plugin-typescript2": "^0.37.0",
|
|
78
|
-
"tsx": "^4.
|
|
76
|
+
"tsx": "^4.23.1",
|
|
79
77
|
"typescript": "^6.0.3",
|
|
80
|
-
"typescript-eslint": "^8.
|
|
81
|
-
"vitest": "^4.1.
|
|
78
|
+
"typescript-eslint": "^8.65.0",
|
|
79
|
+
"vitest": "^4.1.10"
|
|
82
80
|
},
|
|
83
81
|
"repository": {
|
|
84
82
|
"type": "git",
|
|
@@ -114,5 +112,9 @@
|
|
|
114
112
|
},
|
|
115
113
|
"publishConfig": {
|
|
116
114
|
"access": "public"
|
|
115
|
+
},
|
|
116
|
+
"allowScripts": {
|
|
117
|
+
"fsevents@2.3.3": true,
|
|
118
|
+
"esbuild@0.28.1": true
|
|
117
119
|
}
|
|
118
120
|
}
|