@nanocollective/get-md 1.0.2 → 1.1.0-beta.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/LICENSE +1 -1
- package/README.md +155 -1
- package/dist/cli.js +388 -4
- package/dist/cli.js.map +1 -1
- package/dist/cli.spec.js +187 -0
- package/dist/cli.spec.js.map +1 -1
- package/dist/converters/llm-converter.d.ts +71 -0
- package/dist/converters/llm-converter.d.ts.map +1 -0
- package/dist/converters/llm-converter.js +191 -0
- package/dist/converters/llm-converter.js.map +1 -0
- package/dist/converters/llm-converter.spec.d.ts +2 -0
- package/dist/converters/llm-converter.spec.d.ts.map +1 -0
- package/dist/converters/llm-converter.spec.js +281 -0
- package/dist/converters/llm-converter.spec.js.map +1 -0
- package/dist/converters/llm-manager.d.ts +88 -0
- package/dist/converters/llm-manager.d.ts.map +1 -0
- package/dist/converters/llm-manager.js +277 -0
- package/dist/converters/llm-manager.js.map +1 -0
- package/dist/converters/llm-manager.spec.d.ts +2 -0
- package/dist/converters/llm-manager.spec.d.ts.map +1 -0
- package/dist/converters/llm-manager.spec.js +280 -0
- package/dist/converters/llm-manager.spec.js.map +1 -0
- package/dist/extractors/metadata-extractor.js +1 -1
- package/dist/extractors/metadata-extractor.js.map +1 -1
- package/dist/index.d.ts +14 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -10
- package/dist/index.js.map +1 -1
- package/dist/index.spec.js +172 -1
- package/dist/index.spec.js.map +1 -1
- package/dist/optimizers/html-cleaner.js +1 -1
- package/dist/optimizers/html-cleaner.js.map +1 -1
- package/dist/optimizers/html-cleaner.spec.js +1 -0
- package/dist/optimizers/html-cleaner.spec.js.map +1 -1
- package/dist/optimizers/llm-formatter.js +2 -2
- package/dist/optimizers/llm-formatter.js.map +1 -1
- package/dist/optimizers/structure-enhancer.js +3 -3
- package/dist/optimizers/structure-enhancer.js.map +1 -1
- package/dist/optimizers/structure-enhancer.spec.js +1 -1
- package/dist/optimizers/structure-enhancer.spec.js.map +1 -1
- package/dist/parsers/markdown-parser.d.ts +36 -0
- package/dist/parsers/markdown-parser.d.ts.map +1 -1
- package/dist/parsers/markdown-parser.js +267 -45
- package/dist/parsers/markdown-parser.js.map +1 -1
- package/dist/parsers/markdown-parser.spec.js +106 -98
- package/dist/parsers/markdown-parser.spec.js.map +1 -1
- package/dist/types.d.ts +149 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/config-loader.d.ts +62 -0
- package/dist/utils/config-loader.d.ts.map +1 -0
- package/dist/utils/config-loader.js +167 -0
- package/dist/utils/config-loader.js.map +1 -0
- package/dist/utils/config-loader.spec.d.ts +2 -0
- package/dist/utils/config-loader.spec.d.ts.map +1 -0
- package/dist/utils/config-loader.spec.js +355 -0
- package/dist/utils/config-loader.spec.js.map +1 -0
- package/dist/utils/url-fetcher.d.ts.map +1 -1
- package/dist/utils/url-fetcher.js +1 -1
- package/dist/utils/url-fetcher.js.map +1 -1
- package/dist/utils/validators.js +1 -1
- package/dist/utils/validators.js.map +1 -1
- package/package.json +25 -17
package/LICENSE
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
MIT License with Attribution
|
|
4
4
|
|
|
5
|
-
Copyright (c)
|
|
5
|
+
Copyright (c) 2026 Nano Collective
|
|
6
6
|
|
|
7
7
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
8
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -7,10 +7,12 @@ A fast, lightweight HTML to Markdown converter optimized for LLM consumption. Us
|
|
|
7
7
|
- **Lightning-fast**: Converts HTML to Markdown in <100ms
|
|
8
8
|
- **Intelligent extraction**: Uses Mozilla Readability to extract main content
|
|
9
9
|
- **LLM-optimized**: Consistent formatting perfect for AI consumption
|
|
10
|
+
- **Optional AI conversion**: Higher quality output with local ReaderLM-v2 model
|
|
10
11
|
- **CLI included**: Use from the command line or as a library
|
|
11
12
|
- **TypeScript**: Full type definitions included
|
|
12
|
-
- **Zero downloads**:
|
|
13
|
+
- **Zero downloads**: Works instantly (AI model optional, ~1GB)
|
|
13
14
|
- **Lightweight**: Small package size (~10MB)
|
|
15
|
+
- **React Native compatible**: Full support including content extraction!
|
|
14
16
|
|
|
15
17
|
## Installation
|
|
16
18
|
|
|
@@ -174,6 +176,158 @@ getmd article.html --no-images --no-links -o clean.md
|
|
|
174
176
|
getmd article.html --no-frontmatter -o clean.md
|
|
175
177
|
```
|
|
176
178
|
|
|
179
|
+
## React Native Support
|
|
180
|
+
|
|
181
|
+
get-md **fully supports React Native** including content extraction! We use `happy-dom-without-node` instead of JSDOM, which works across Node.js, React Native, and browser environments.
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { convertToMarkdown } from "@nanocollective/get-md";
|
|
185
|
+
|
|
186
|
+
// Works in React Native with full features!
|
|
187
|
+
const result = await convertToMarkdown(html, {
|
|
188
|
+
extractContent: true, // Readability extraction works!
|
|
189
|
+
includeMeta: true,
|
|
190
|
+
// ... all other options work
|
|
191
|
+
});
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**All features work in React Native:**
|
|
195
|
+
- ✅ HTML to Markdown conversion
|
|
196
|
+
- ✅ Mozilla Readability content extraction
|
|
197
|
+
- ✅ Metadata extraction
|
|
198
|
+
- ✅ Content cleaning and optimization
|
|
199
|
+
- ✅ All formatting options
|
|
200
|
+
|
|
201
|
+
No special configuration needed!
|
|
202
|
+
|
|
203
|
+
## LLM-Powered Conversion (Optional)
|
|
204
|
+
|
|
205
|
+
For even higher quality markdown output, get-md supports optional AI-powered conversion using a local LLM model. This uses [ReaderLM-v2](https://huggingface.co/jinaai/ReaderLM-v2), a model specifically trained for HTML-to-Markdown conversion.
|
|
206
|
+
|
|
207
|
+
### When to Use LLM Conversion
|
|
208
|
+
|
|
209
|
+
| Use Case | Recommended Method |
|
|
210
|
+
|----------|-------------------|
|
|
211
|
+
| High-quality single conversions | LLM (better structure) |
|
|
212
|
+
| Complex documentation sites | LLM (semantic understanding) |
|
|
213
|
+
| Batch processing (1000+ pages) | Turndown (speed) |
|
|
214
|
+
| CI/CD pipelines | Turndown (fast, deterministic) |
|
|
215
|
+
| Real-time conversion | Turndown (sub-second) |
|
|
216
|
+
|
|
217
|
+
### Quick Start
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
import { convertToMarkdown, checkLLMModel, downloadLLMModel } from '@nanocollective/get-md';
|
|
221
|
+
|
|
222
|
+
// 1. Check if model is available
|
|
223
|
+
const status = await checkLLMModel();
|
|
224
|
+
|
|
225
|
+
if (!status.available) {
|
|
226
|
+
// 2. Download model (one-time, ~986MB)
|
|
227
|
+
await downloadLLMModel({
|
|
228
|
+
onProgress: (downloaded, total, percentage) => {
|
|
229
|
+
console.log(`Downloading: ${percentage.toFixed(1)}%`);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// 3. Convert with LLM
|
|
235
|
+
const result = await convertToMarkdown('https://example.com', {
|
|
236
|
+
useLLM: true,
|
|
237
|
+
onLLMEvent: (event) => {
|
|
238
|
+
if (event.type === 'conversion-complete') {
|
|
239
|
+
console.log(`Done in ${event.duration}ms`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### CLI Usage
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
# Check model status
|
|
249
|
+
getmd --model-info
|
|
250
|
+
|
|
251
|
+
# Download model (one-time)
|
|
252
|
+
getmd --download-model
|
|
253
|
+
|
|
254
|
+
# Convert with LLM
|
|
255
|
+
getmd https://example.com --use-llm
|
|
256
|
+
|
|
257
|
+
# Compare Turndown vs LLM
|
|
258
|
+
getmd https://example.com --compare -o comparison.md
|
|
259
|
+
|
|
260
|
+
# Show default model path
|
|
261
|
+
getmd --model-path
|
|
262
|
+
|
|
263
|
+
# Remove model
|
|
264
|
+
getmd --remove-model
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Configuration File
|
|
268
|
+
|
|
269
|
+
You can set default options in a config file. Create `.getmdrc` or `get-md.config.json` in your project or home directory:
|
|
270
|
+
|
|
271
|
+
```json
|
|
272
|
+
{
|
|
273
|
+
"useLLM": true,
|
|
274
|
+
"llmTemperature": 0.1,
|
|
275
|
+
"llmFallback": true,
|
|
276
|
+
"extractContent": true,
|
|
277
|
+
"includeMeta": true
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
CLI flags override config file settings. Use `getmd --show-config` to see current configuration.
|
|
282
|
+
|
|
283
|
+
### LLM Options
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
{
|
|
287
|
+
useLLM?: boolean; // Use LLM for conversion (default: false)
|
|
288
|
+
llmModelPath?: string; // Custom model path (optional)
|
|
289
|
+
llmTemperature?: number; // Generation temperature (default: 0.1)
|
|
290
|
+
llmMaxTokens?: number; // Max tokens (default: 512000)
|
|
291
|
+
llmFallback?: boolean; // Fallback to Turndown on error (default: true)
|
|
292
|
+
|
|
293
|
+
// Event callbacks
|
|
294
|
+
onLLMEvent?: (event: LLMEvent) => void;
|
|
295
|
+
onDownloadProgress?: (downloaded, total, percentage) => void;
|
|
296
|
+
onModelStatus?: (status) => void;
|
|
297
|
+
onConversionProgress?: (progress) => void;
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Requirements
|
|
302
|
+
|
|
303
|
+
- **Disk Space**: ~1GB for the model file
|
|
304
|
+
- **RAM**: 2-4GB during inference (8GB+ system recommended)
|
|
305
|
+
- **Speed**: 5-10 seconds per typical webpage (vs <100ms for Turndown)
|
|
306
|
+
|
|
307
|
+
### Model Management
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
import {
|
|
311
|
+
checkLLMModel,
|
|
312
|
+
downloadLLMModel,
|
|
313
|
+
removeLLMModel,
|
|
314
|
+
getLLMModelInfo
|
|
315
|
+
} from '@nanocollective/get-md';
|
|
316
|
+
|
|
317
|
+
// Check model availability
|
|
318
|
+
const status = await checkLLMModel();
|
|
319
|
+
console.log(status.available); // true/false
|
|
320
|
+
console.log(status.sizeFormatted); // "986MB"
|
|
321
|
+
|
|
322
|
+
// Get model information
|
|
323
|
+
const info = getLLMModelInfo();
|
|
324
|
+
console.log(info.defaultPath); // ~/.get-md/models/ReaderLM-v2-Q4_K_M.gguf
|
|
325
|
+
console.log(info.recommendedModel); // "ReaderLM-v2-Q4_K_M"
|
|
326
|
+
|
|
327
|
+
// Remove model
|
|
328
|
+
await removeLLMModel();
|
|
329
|
+
```
|
|
330
|
+
|
|
177
331
|
## Why get-md?
|
|
178
332
|
|
|
179
333
|
### For LLMs
|
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// src/cli.ts
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import readline from "node:readline";
|
|
5
|
+
import { Presets, SingleBar } from "cli-progress";
|
|
3
6
|
import { Command } from "commander";
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
7
|
+
import { checkLLMModel, convertToMarkdown, downloadLLMModel, getLLMModelInfo, removeLLMModel, } from "./index.js";
|
|
8
|
+
import { findConfigPath, loadConfig, mergeConfigWithOptions, } from "./utils/config-loader.js";
|
|
6
9
|
const program = new Command();
|
|
7
10
|
program
|
|
8
11
|
.name("get-md")
|
|
@@ -20,10 +23,50 @@ program
|
|
|
20
23
|
.option("--max-length <n>", "Maximum output length", "1000000")
|
|
21
24
|
.option("--base-url <url>", "Base URL for resolving relative links")
|
|
22
25
|
.option("-v, --verbose", "Verbose output")
|
|
26
|
+
// LLM options
|
|
27
|
+
.option("--use-llm", "Use LLM for higher quality HTML to Markdown conversion")
|
|
28
|
+
.option("--llm-model-path <path>", "Custom path to LLM model file")
|
|
29
|
+
.option("--llm-temperature <n>", "LLM temperature (default: 0.1)")
|
|
30
|
+
// Model management commands
|
|
31
|
+
.option("--download-model", "Download the LLM model")
|
|
32
|
+
.option("--model-info", "Show LLM model information and status")
|
|
33
|
+
.option("--remove-model", "Remove the downloaded LLM model")
|
|
34
|
+
.option("--model-path", "Show default model storage path")
|
|
35
|
+
// Config options
|
|
36
|
+
.option("--config <path>", "Path to config file")
|
|
37
|
+
.option("--show-config", "Show current configuration and exit")
|
|
38
|
+
// Comparison mode
|
|
39
|
+
.option("--compare", "Compare Turndown vs LLM conversion side-by-side")
|
|
23
40
|
.action(async (input, options) => {
|
|
24
41
|
try {
|
|
42
|
+
// Handle model management commands first
|
|
43
|
+
if (options.modelInfo) {
|
|
44
|
+
await handleModelInfo();
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (options.downloadModel) {
|
|
48
|
+
await handleDownloadModel();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (options.removeModel) {
|
|
52
|
+
await handleRemoveModel();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (options.modelPath) {
|
|
56
|
+
handleModelPath();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (options.showConfig) {
|
|
60
|
+
handleShowConfig(options.config);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
25
63
|
// Get input HTML
|
|
26
64
|
const html = await getInput(input);
|
|
65
|
+
// Comparison mode
|
|
66
|
+
if (options.compare) {
|
|
67
|
+
await handleComparisonMode(html, options);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
27
70
|
// Markdown conversion mode
|
|
28
71
|
await handleMarkdownConversion(html, options);
|
|
29
72
|
}
|
|
@@ -37,7 +80,7 @@ program
|
|
|
37
80
|
});
|
|
38
81
|
async function getInput(input) {
|
|
39
82
|
// Read from URL
|
|
40
|
-
if (input
|
|
83
|
+
if (input?.startsWith("http")) {
|
|
41
84
|
const response = await fetch(input, {
|
|
42
85
|
signal: AbortSignal.timeout(15000),
|
|
43
86
|
});
|
|
@@ -61,7 +104,10 @@ async function getInput(input) {
|
|
|
61
104
|
throw new Error("No input provided. Provide a file path, URL, or pipe to stdin.");
|
|
62
105
|
}
|
|
63
106
|
async function handleMarkdownConversion(html, options) {
|
|
64
|
-
|
|
107
|
+
// Load config from file(s)
|
|
108
|
+
const fileConfig = loadConfig();
|
|
109
|
+
// Build options from CLI flags
|
|
110
|
+
const cliOptions = {
|
|
65
111
|
extractContent: options.extract,
|
|
66
112
|
includeMeta: options.frontmatter,
|
|
67
113
|
includeImages: options.images,
|
|
@@ -69,7 +115,39 @@ async function handleMarkdownConversion(html, options) {
|
|
|
69
115
|
includeTables: options.tables,
|
|
70
116
|
maxLength: parseInt(options.maxLength, 10),
|
|
71
117
|
baseUrl: options.baseUrl,
|
|
118
|
+
// LLM options from CLI
|
|
119
|
+
useLLM: options.useLlm,
|
|
120
|
+
llmModelPath: options.llmModelPath,
|
|
121
|
+
llmTemperature: options.llmTemperature
|
|
122
|
+
? parseFloat(options.llmTemperature)
|
|
123
|
+
: undefined,
|
|
124
|
+
// Event callbacks for CLI feedback - always show progress for LLM since it can be slow
|
|
125
|
+
onLLMEvent: options.useLlm
|
|
126
|
+
? options.verbose
|
|
127
|
+
? createLLMEventHandler()
|
|
128
|
+
: createMinimalLLMEventHandler()
|
|
129
|
+
: undefined,
|
|
72
130
|
};
|
|
131
|
+
// Merge config with CLI options (CLI takes precedence)
|
|
132
|
+
const conversionOptions = mergeConfigWithOptions(fileConfig, cliOptions);
|
|
133
|
+
// Check if LLM mode is requested (from config or CLI)
|
|
134
|
+
if (conversionOptions.useLLM) {
|
|
135
|
+
// Check if model is available
|
|
136
|
+
const status = await checkLLMModel({
|
|
137
|
+
modelPath: conversionOptions.llmModelPath,
|
|
138
|
+
});
|
|
139
|
+
if (!status.available) {
|
|
140
|
+
// Prompt user to download
|
|
141
|
+
const shouldDownload = await promptYesNo("LLM model not found. Download ReaderLM-v2 (986MB)?");
|
|
142
|
+
if (shouldDownload) {
|
|
143
|
+
await handleDownloadModel();
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
console.error("LLM mode requires the model. Falling back to Turndown.");
|
|
147
|
+
conversionOptions.useLLM = false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
73
151
|
const result = await convertToMarkdown(html, conversionOptions);
|
|
74
152
|
// Write output
|
|
75
153
|
if (options.output) {
|
|
@@ -87,5 +165,311 @@ async function handleMarkdownConversion(html, options) {
|
|
|
87
165
|
console.log(result.markdown);
|
|
88
166
|
}
|
|
89
167
|
}
|
|
168
|
+
// ============================================================================
|
|
169
|
+
// Model Management Commands
|
|
170
|
+
// ============================================================================
|
|
171
|
+
async function handleModelInfo() {
|
|
172
|
+
const info = getLLMModelInfo();
|
|
173
|
+
const status = await checkLLMModel();
|
|
174
|
+
console.log("\nLLM Model Information");
|
|
175
|
+
console.log("=====================");
|
|
176
|
+
console.log(`Recommended model: ${info.recommendedModel}`);
|
|
177
|
+
console.log(`Default path: ${info.defaultPath}`);
|
|
178
|
+
console.log(`Status: ${status.available ? "Installed" : "Not installed"}`);
|
|
179
|
+
if (status.available) {
|
|
180
|
+
console.log(`Size: ${status.sizeFormatted}`);
|
|
181
|
+
}
|
|
182
|
+
console.log("\nAvailable variants:");
|
|
183
|
+
for (const variant of info.availableModels) {
|
|
184
|
+
const marker = variant.name === info.recommendedModel ? " (recommended)" : "";
|
|
185
|
+
console.log(` - ${variant.name}${marker}`);
|
|
186
|
+
console.log(` Size: ${Math.round(variant.size / (1024 * 1024))}MB`);
|
|
187
|
+
console.log(` RAM required: ${variant.ramRequired}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async function handleDownloadModel() {
|
|
191
|
+
const status = await checkLLMModel();
|
|
192
|
+
if (status.available) {
|
|
193
|
+
console.log(`Model already installed at: ${status.path}`);
|
|
194
|
+
console.log(`Size: ${status.sizeFormatted}`);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
console.log("Downloading ReaderLM-v2 model...\n");
|
|
198
|
+
// Create progress bar
|
|
199
|
+
const progressBar = new SingleBar({
|
|
200
|
+
format: "Progress |{bar}| {percentage}% | {downloaded}/{totalSize}",
|
|
201
|
+
hideCursor: true,
|
|
202
|
+
}, Presets.shades_classic);
|
|
203
|
+
let started = false;
|
|
204
|
+
try {
|
|
205
|
+
const path = await downloadLLMModel({
|
|
206
|
+
onProgress: (downloaded, total, percentage) => {
|
|
207
|
+
if (!started) {
|
|
208
|
+
progressBar.start(100, 0, {
|
|
209
|
+
downloaded: formatBytes(downloaded),
|
|
210
|
+
totalSize: formatBytes(total),
|
|
211
|
+
});
|
|
212
|
+
started = true;
|
|
213
|
+
}
|
|
214
|
+
progressBar.update(Math.round(percentage), {
|
|
215
|
+
downloaded: formatBytes(downloaded),
|
|
216
|
+
totalSize: formatBytes(total),
|
|
217
|
+
});
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
progressBar.stop();
|
|
221
|
+
console.log(`\n✓ Model downloaded successfully to: ${path}`);
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
progressBar.stop();
|
|
225
|
+
throw error;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
async function handleRemoveModel() {
|
|
229
|
+
const status = await checkLLMModel();
|
|
230
|
+
if (!status.available) {
|
|
231
|
+
console.log("No model installed.");
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const confirm = await promptYesNo(`Remove model at ${status.path}? (${status.sizeFormatted})`);
|
|
235
|
+
if (confirm) {
|
|
236
|
+
await removeLLMModel();
|
|
237
|
+
console.log("✓ Model removed successfully.");
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
console.log("Cancelled.");
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
function handleModelPath() {
|
|
244
|
+
const info = getLLMModelInfo();
|
|
245
|
+
console.log(info.defaultPath);
|
|
246
|
+
}
|
|
247
|
+
async function handleComparisonMode(html, options) {
|
|
248
|
+
// Check if LLM model is available
|
|
249
|
+
const status = await checkLLMModel({
|
|
250
|
+
modelPath: options.llmModelPath,
|
|
251
|
+
});
|
|
252
|
+
if (!status.available) {
|
|
253
|
+
const shouldDownload = await promptYesNo("LLM model not found. Download ReaderLM-v2 (986MB) to run comparison?");
|
|
254
|
+
if (shouldDownload) {
|
|
255
|
+
await handleDownloadModel();
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
console.error("Cannot run comparison without LLM model.");
|
|
259
|
+
process.exit(1);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
console.log("\nRunning comparison: Turndown vs LLM\n");
|
|
263
|
+
console.log("=".repeat(50));
|
|
264
|
+
// Common options
|
|
265
|
+
const baseOptions = {
|
|
266
|
+
extractContent: options.extract,
|
|
267
|
+
includeMeta: options.frontmatter,
|
|
268
|
+
includeImages: options.images,
|
|
269
|
+
includeLinks: options.links,
|
|
270
|
+
includeTables: options.tables,
|
|
271
|
+
maxLength: parseInt(options.maxLength, 10),
|
|
272
|
+
baseUrl: options.baseUrl,
|
|
273
|
+
};
|
|
274
|
+
// Run Turndown conversion
|
|
275
|
+
console.log("\n[1/2] Converting with Turndown...");
|
|
276
|
+
const turndownStart = Date.now();
|
|
277
|
+
const turndownResult = await convertToMarkdown(html, {
|
|
278
|
+
...baseOptions,
|
|
279
|
+
useLLM: false,
|
|
280
|
+
});
|
|
281
|
+
const turndownTime = Date.now() - turndownStart;
|
|
282
|
+
console.log(` Done in ${turndownTime}ms`);
|
|
283
|
+
// Run LLM conversion
|
|
284
|
+
console.log("\n[2/2] Converting with LLM...");
|
|
285
|
+
const llmStart = Date.now();
|
|
286
|
+
const llmResult = await convertToMarkdown(html, {
|
|
287
|
+
...baseOptions,
|
|
288
|
+
useLLM: true,
|
|
289
|
+
llmModelPath: options.llmModelPath,
|
|
290
|
+
llmTemperature: options.llmTemperature
|
|
291
|
+
? parseFloat(options.llmTemperature)
|
|
292
|
+
: undefined,
|
|
293
|
+
});
|
|
294
|
+
const llmTime = Date.now() - llmStart;
|
|
295
|
+
console.log(` Done in ${llmTime}ms`);
|
|
296
|
+
// Print comparison table
|
|
297
|
+
console.log(`\n${"=".repeat(50)}`);
|
|
298
|
+
console.log("\nComparison Results");
|
|
299
|
+
console.log("-".repeat(50));
|
|
300
|
+
console.log(`| ${"Method".padEnd(12)} | ${"Time".padEnd(10)} | ${"Output Size".padEnd(12)} |`);
|
|
301
|
+
console.log(`| ${"-".repeat(12)} | ${"-".repeat(10)} | ${"-".repeat(12)} |`);
|
|
302
|
+
console.log(`| ${"Turndown".padEnd(12)} | ${formatTime(turndownTime).padEnd(10)} | ${formatBytes(turndownResult.stats.outputLength).padEnd(12)} |`);
|
|
303
|
+
console.log(`| ${"LLM".padEnd(12)} | ${formatTime(llmTime).padEnd(10)} | ${formatBytes(llmResult.stats.outputLength).padEnd(12)} |`);
|
|
304
|
+
console.log("-".repeat(50));
|
|
305
|
+
// Speed comparison
|
|
306
|
+
const speedRatio = llmTime / turndownTime;
|
|
307
|
+
console.log(`\nSpeed: LLM is ${speedRatio.toFixed(1)}x slower than Turndown`);
|
|
308
|
+
// Size comparison
|
|
309
|
+
const sizeDiff = llmResult.stats.outputLength - turndownResult.stats.outputLength;
|
|
310
|
+
const sizePercent = ((sizeDiff / turndownResult.stats.outputLength) *
|
|
311
|
+
100).toFixed(1);
|
|
312
|
+
if (sizeDiff > 0) {
|
|
313
|
+
console.log(`Size: LLM output is ${formatBytes(sizeDiff)} larger (+${sizePercent}%)`);
|
|
314
|
+
}
|
|
315
|
+
else if (sizeDiff < 0) {
|
|
316
|
+
console.log(`Size: LLM output is ${formatBytes(Math.abs(sizeDiff))} smaller (${sizePercent}%)`);
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
console.log("Size: Outputs are the same size");
|
|
320
|
+
}
|
|
321
|
+
// Write outputs if requested
|
|
322
|
+
if (options.output) {
|
|
323
|
+
const baseName = options.output.replace(/\.md$/, "");
|
|
324
|
+
const turndownFile = `${baseName}.turndown.md`;
|
|
325
|
+
const llmFile = `${baseName}.llm.md`;
|
|
326
|
+
await fs.writeFile(turndownFile, turndownResult.markdown, "utf-8");
|
|
327
|
+
await fs.writeFile(llmFile, llmResult.markdown, "utf-8");
|
|
328
|
+
console.log(`\nOutputs written to:`);
|
|
329
|
+
console.log(` - ${turndownFile}`);
|
|
330
|
+
console.log(` - ${llmFile}`);
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
console.log("\nTip: Use -o <file> to save outputs for detailed comparison");
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
function formatTime(ms) {
|
|
337
|
+
if (ms < 1000)
|
|
338
|
+
return `${ms}ms`;
|
|
339
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
340
|
+
}
|
|
341
|
+
function handleShowConfig(configPath) {
|
|
342
|
+
const configFile = configPath || findConfigPath();
|
|
343
|
+
console.log("\nConfiguration");
|
|
344
|
+
console.log("=============");
|
|
345
|
+
if (configFile) {
|
|
346
|
+
console.log(`Config file: ${configFile}`);
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
console.log("Config file: None found");
|
|
350
|
+
console.log("\nSupported config file names:");
|
|
351
|
+
console.log(" - .getmdrc");
|
|
352
|
+
console.log(" - .getmdrc.json");
|
|
353
|
+
console.log(" - get-md.config.json");
|
|
354
|
+
console.log(" - getmd.config.json");
|
|
355
|
+
console.log("\nSearch locations:");
|
|
356
|
+
console.log(" 1. Current working directory");
|
|
357
|
+
console.log(" 2. Home directory (~/)");
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
try {
|
|
361
|
+
const config = loadConfig();
|
|
362
|
+
console.log("\nLoaded configuration:");
|
|
363
|
+
console.log(JSON.stringify(config, null, 2));
|
|
364
|
+
}
|
|
365
|
+
catch (error) {
|
|
366
|
+
console.error(`\nError loading config: ${error instanceof Error ? error.message : String(error)}`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
// ============================================================================
|
|
370
|
+
// Helper Functions
|
|
371
|
+
// ============================================================================
|
|
372
|
+
function formatBytes(bytes) {
|
|
373
|
+
if (bytes < 1024)
|
|
374
|
+
return `${bytes}B`;
|
|
375
|
+
if (bytes < 1024 * 1024)
|
|
376
|
+
return `${(bytes / 1024).toFixed(1)}KB`;
|
|
377
|
+
if (bytes < 1024 * 1024 * 1024)
|
|
378
|
+
return `${(bytes / (1024 * 1024)).toFixed(0)}MB`;
|
|
379
|
+
return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)}GB`;
|
|
380
|
+
}
|
|
381
|
+
async function promptYesNo(question) {
|
|
382
|
+
// Non-interactive mode - default to no
|
|
383
|
+
if (!process.stdin.isTTY) {
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
const rl = readline.createInterface({
|
|
387
|
+
input: process.stdin,
|
|
388
|
+
output: process.stderr,
|
|
389
|
+
});
|
|
390
|
+
return new Promise((resolve) => {
|
|
391
|
+
rl.question(`${question} (y/N) `, (answer) => {
|
|
392
|
+
rl.close();
|
|
393
|
+
resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
function createMinimalLLMEventHandler() {
|
|
398
|
+
return (event) => {
|
|
399
|
+
// Show minimal progress for LLM operations without verbose mode
|
|
400
|
+
if (process.stdout.isTTY) {
|
|
401
|
+
switch (event.type) {
|
|
402
|
+
case "llama-init-start":
|
|
403
|
+
process.stderr.write("Initializing LLM (may take a few minutes on first run)... ");
|
|
404
|
+
break;
|
|
405
|
+
case "llama-init-complete":
|
|
406
|
+
process.stderr.write("done\n");
|
|
407
|
+
break;
|
|
408
|
+
case "model-file-loading":
|
|
409
|
+
process.stderr.write("Loading model... ");
|
|
410
|
+
break;
|
|
411
|
+
case "model-loaded":
|
|
412
|
+
process.stderr.write("done\n");
|
|
413
|
+
break;
|
|
414
|
+
case "conversion-start":
|
|
415
|
+
process.stderr.write("Converting... ");
|
|
416
|
+
break;
|
|
417
|
+
case "conversion-complete":
|
|
418
|
+
process.stderr.write("done\n");
|
|
419
|
+
break;
|
|
420
|
+
case "fallback-start":
|
|
421
|
+
process.stderr.write(`Falling back to Turndown: ${event.reason}\n`);
|
|
422
|
+
break;
|
|
423
|
+
case "conversion-error":
|
|
424
|
+
process.stderr.write(`Error: ${event.error.message}\n`);
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
function createLLMEventHandler() {
|
|
431
|
+
return (event) => {
|
|
432
|
+
switch (event.type) {
|
|
433
|
+
case "model-check":
|
|
434
|
+
if (event.status === "checking") {
|
|
435
|
+
process.stderr.write("Checking model... ");
|
|
436
|
+
}
|
|
437
|
+
else if (event.status === "found") {
|
|
438
|
+
process.stderr.write("found\n");
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
process.stderr.write("not found\n");
|
|
442
|
+
}
|
|
443
|
+
break;
|
|
444
|
+
case "model-loading":
|
|
445
|
+
process.stderr.write(`Loading ${event.modelName}...\n`);
|
|
446
|
+
break;
|
|
447
|
+
case "llama-init-start":
|
|
448
|
+
process.stderr.write(" Initializing llama.cpp (may take a few minutes on first run)... ");
|
|
449
|
+
break;
|
|
450
|
+
case "llama-init-complete":
|
|
451
|
+
process.stderr.write("done\n");
|
|
452
|
+
break;
|
|
453
|
+
case "model-file-loading":
|
|
454
|
+
process.stderr.write(" Loading model file... ");
|
|
455
|
+
break;
|
|
456
|
+
case "model-loaded":
|
|
457
|
+
process.stderr.write(`done (${event.loadTime}ms total)\n`);
|
|
458
|
+
break;
|
|
459
|
+
case "conversion-start":
|
|
460
|
+
process.stderr.write(`Converting ${formatBytes(event.inputSize)} of HTML... `);
|
|
461
|
+
break;
|
|
462
|
+
case "conversion-complete":
|
|
463
|
+
process.stderr.write(`done (${event.duration}ms)\n`);
|
|
464
|
+
break;
|
|
465
|
+
case "fallback-start":
|
|
466
|
+
process.stderr.write(`\nFalling back to Turndown: ${event.reason}\n`);
|
|
467
|
+
break;
|
|
468
|
+
case "conversion-error":
|
|
469
|
+
process.stderr.write(`\nError: ${event.error.message}\n`);
|
|
470
|
+
break;
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
}
|
|
90
474
|
program.parse();
|
|
91
475
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|