@heripo/research-radar 2.3.1 → 2.3.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 (2) hide show
  1. package/README.md +33 -8
  2. package/package.json +11 -11
package/README.md CHANGED
@@ -24,7 +24,7 @@ An AI-powered newsletter service for Korean cultural heritage. Built on [`@llm-n
24
24
  - Type-safe TypeScript with strict interfaces
25
25
  - Provider pattern for swapping components (Crawling/Analysis/Content/Email)
26
26
  - 66 crawling targets across heritage agencies, museums, academic societies
27
- - LLM-driven analysis (GPT-5 models)
27
+ - Dual LLM providers: OpenAI GPT-5 (analysis) + Google Gemini (content generation)
28
28
  - Built-in retries, chain options, preview emails
29
29
 
30
30
  **Links**: [Live service](https://heripo.com/research-radar/subscribe) • [Newsletter example](https://heripo.com/research-radar-newsletter-example.html) • [Core engine](https://github.com/heripo-lab/llm-newsletter-kit-core)
@@ -69,7 +69,7 @@ For academic publications:
69
69
  npm install @heripo/research-radar @llm-newsletter-kit/core
70
70
  ```
71
71
 
72
- **Requirements**: Node.js >= 22, OpenAI API key
72
+ **Requirements**: Node.js >= 22, OpenAI API key, Google Generative AI API key
73
73
 
74
74
  **Note**: `@llm-newsletter-kit/core` is a peer dependency and must be installed separately.
75
75
 
@@ -80,6 +80,7 @@ import { generateNewsletter } from '@heripo/research-radar';
80
80
 
81
81
  const newsletterId = await generateNewsletter({
82
82
  openAIApiKey: process.env.OPENAI_API_KEY,
83
+ googleGenerativeAIApiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY,
83
84
 
84
85
  // Implement these repository interfaces (see src/types/dependencies.ts)
85
86
  taskRepository: {
@@ -104,8 +105,11 @@ const newsletterId = await generateNewsletter({
104
105
  saveNewsletter: async (data) => db.newsletters.save(data),
105
106
  },
106
107
 
107
- // Optional: Custom logger and preview
108
+ // Optional parameters:
108
109
  logger: console,
110
+ publishDate: '2026-02-20', // Override publication date (ISO format)
111
+ templateOptions: { /* ... */ }, // Newsletter template customization
112
+ customFetch: proxyFetch, // Custom fetch for proxy-based crawling
109
113
  previewNewsletter: {
110
114
  fetchNewsletterForPreview: async () => db.newsletters.latest(),
111
115
  emailService: resendEmailService,
@@ -135,7 +139,7 @@ Uses the **Provider-Service pattern** from `@llm-newsletter-kit/core`. See [core
135
139
 
136
140
  **Parsers** (`src/parsers/`): Custom extractors per organization
137
141
 
138
- **Template** (`src/templates/newsletter-html.ts`): Responsive email with light/dark mode
142
+ **Templates** (`src/templates/`): `newsletter-html.ts` (responsive email with light/dark mode), `welcome-html.ts` (`generateWelcomeHTML()`), `shared.ts` (shared HTML components)
139
143
 
140
144
  ## Development commands
141
145
 
@@ -158,6 +162,7 @@ A web-based tool for testing crawling parsers during development. Built with Exp
158
162
 
159
163
  ```bash
160
164
  npm run dev:crawler # Start at http://localhost:3333
165
+ npm run dev:crawler:proxy # Start with proxy support (uses .env)
161
166
  ```
162
167
 
163
168
  **Features**:
@@ -167,6 +172,26 @@ npm run dev:crawler # Start at http://localhost:3333
167
172
  - 5-minute response cache (with skip/clear options)
168
173
  - Timing info for fetch and parse operations
169
174
 
175
+ ### Newsletter Preview
176
+
177
+ Preview rendered newsletter HTML with sample content.
178
+
179
+ ```bash
180
+ npm run dev:newsletter-preview # Start at http://localhost:3334
181
+ ```
182
+
183
+ Query params: `?kras=true` (KRAS mode), `?krasNews=true` (KRAS news section), `?heripolabNews=true` (heripo lab news section)
184
+
185
+ ### Welcome Email Preview
186
+
187
+ Preview rendered welcome email HTML.
188
+
189
+ ```bash
190
+ npm run dev:welcome-preview # Start at http://localhost:3335
191
+ ```
192
+
193
+ Query params: `?kras=true` (KRAS mode), `?name=홍길동` (subscriber name)
194
+
170
195
  ## 🤝 Contributing
171
196
 
172
197
  You can use this project in two ways:
@@ -197,14 +222,14 @@ subscribeUrl: 'https://yourdomain.com/subscribe'
197
222
 
198
223
  **4. Switch LLM provider** (optional):
199
224
 
200
- To use Anthropic/Gemini/Ollama instead of OpenAI:
201
- - `src/newsletter-generator.ts`: Change `createOpenAI()` to your provider
225
+ Currently uses dual providers: **OpenAI** (analysis) + **Google Gemini** (content generation). To change:
226
+ - `src/newsletter-generator.ts`: Change `createOpenAI()` / `createGoogleGenerativeAI()` to your provider
202
227
  - `src/providers/analysis.provider.ts`: Update model names (currently `gpt-5-mini`, `gpt-5.1`)
203
- - `src/providers/content-generate.provider.ts`: Update model name
228
+ - `src/providers/content-generate.provider.ts`: Update model name (currently `gemini-3-pro-preview`)
204
229
 
205
230
  Any [Vercel AI SDK provider](https://sdk.vercel.ai/providers) works.
206
231
 
207
- **Search keywords**: `heripo`, `kimhongyeon`, `#D2691E`, `openai`, `gpt-5`
232
+ **Search keywords**: `heripo`, `kimhongyeon`, `#D2691E`, `openai`, `gpt-5`, `google`, `GoogleGenerativeAI`, `gemini`, `createGoogleGenerativeAI`
208
233
 
209
234
  ## Why Code-Based?
210
235
 
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@heripo/research-radar",
3
3
  "private": false,
4
4
  "type": "module",
5
- "version": "2.3.1",
5
+ "version": "2.3.2",
6
6
  "description": "AI-driven intelligence for Korean cultural heritage. This package serves as both a ready-to-use newsletter service and a practical implementation example for the LLM-Newsletter-Kit.",
7
7
  "main": "dist/index.cjs",
8
8
  "module": "dist/index.js",
@@ -45,11 +45,11 @@
45
45
  "author": "kimhongyeon",
46
46
  "license": "Apache-2.0",
47
47
  "dependencies": {
48
- "@ai-sdk/google": "^3.0.29",
49
- "@ai-sdk/openai": "^3.0.28",
48
+ "@ai-sdk/google": "^3.0.30",
49
+ "@ai-sdk/openai": "^3.0.30",
50
50
  "cheerio": "^1.2.0",
51
51
  "dompurify": "^3.3.1",
52
- "jsdom": "^28.0.0",
52
+ "jsdom": "^28.1.0",
53
53
  "juice": "^11.1.1",
54
54
  "safe-markdown2html": "^1.0.0",
55
55
  "turndown": "^7.2.2"
@@ -58,24 +58,24 @@
58
58
  "@llm-newsletter-kit/core": "~1.3.0"
59
59
  },
60
60
  "devDependencies": {
61
- "@eslint/js": "^9.39.2",
62
- "@llm-newsletter-kit/core": "^1.3.1",
61
+ "@eslint/js": "^10.0.1",
62
+ "@llm-newsletter-kit/core": "^1.3.3",
63
63
  "@trivago/prettier-plugin-sort-imports": "^6.0.2",
64
64
  "@types/express": "^5.0.6",
65
65
  "@types/jsdom": "^27.0.0",
66
- "@types/node": "^25.2.3",
66
+ "@types/node": "^25.3.0",
67
67
  "@types/turndown": "^5.0.6",
68
- "eslint": "^9.39.2",
68
+ "eslint": "^10.0.1",
69
69
  "eslint-plugin-unused-imports": "^4.4.1",
70
70
  "express": "^5.2.1",
71
71
  "prettier": "^3.8.1",
72
- "rimraf": "^6.1.2",
73
- "rollup": "^4.57.1",
72
+ "rimraf": "^6.1.3",
73
+ "rollup": "^4.58.0",
74
74
  "rollup-plugin-dts": "^6.3.0",
75
75
  "rollup-plugin-typescript2": "^0.36.0",
76
76
  "tsx": "^4.21.0",
77
77
  "typescript": "^5.9.3",
78
- "typescript-eslint": "^8.55.0"
78
+ "typescript-eslint": "^8.56.0"
79
79
  },
80
80
  "repository": {
81
81
  "type": "git",