doc2vec 2.2.0 → 2.4.0
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 +68 -8
- package/dist/content-processor.js +682 -109
- package/dist/database.js +95 -5
- package/dist/doc2vec.js +143 -250
- package/dist/utils.js +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ The primary goal is to prepare documentation content for Retrieval-Augmented Gen
|
|
|
11
11
|
## Key Features
|
|
12
12
|
|
|
13
13
|
* **Website Crawling:** Recursively crawls websites starting from a given base URL.
|
|
14
|
-
* **Sitemap Support:** Extracts URLs from XML sitemaps to discover pages not linked in navigation.
|
|
14
|
+
* **Sitemap Support:** Extracts URLs from XML sitemaps to discover pages not linked in navigation. When sitemaps include `<lastmod>` dates, pages are skipped without any HTTP requests if the date hasn't changed since the last sync.
|
|
15
15
|
* **PDF Support:** Automatically downloads and processes PDF files linked from websites.
|
|
16
16
|
* **GitHub Issues Integration:** Retrieves GitHub issues and comments, processing them into searchable chunks.
|
|
17
17
|
* **Zendesk Integration:** Fetches support tickets and knowledge base articles from Zendesk, converting them to searchable chunks.
|
|
@@ -28,6 +28,7 @@ The primary goal is to prepare documentation content for Retrieval-Augmented Gen
|
|
|
28
28
|
* **Content Extraction:** Uses Puppeteer for rendering JavaScript-heavy pages and `@mozilla/readability` to extract the main article content.
|
|
29
29
|
* **Smart H1 Preservation:** Automatically extracts and preserves page titles (H1 headings) that Readability might strip as "page chrome", ensuring proper heading hierarchy.
|
|
30
30
|
* **Flexible Content Selectors:** Supports multiple content container patterns (`.docs-content`, `.doc-content`, `.markdown-body`, `article`, etc.) for better compatibility with various documentation sites.
|
|
31
|
+
* **Tabbed Content Support:** Automatically detects WAI-ARIA tabs (`role="tab"` / `role="tabpanel"`) and injects tab labels into panel content so each tab's context is preserved after conversion to Markdown.
|
|
31
32
|
* **HTML to Markdown:** Converts extracted HTML to clean Markdown using `turndown`, preserving code blocks and basic formatting.
|
|
32
33
|
* **Clean Heading Text:** Automatically removes anchor links (like `[](#section-id)`) from heading text for cleaner hierarchy display.
|
|
33
34
|
* **Intelligent Chunking:** Splits Markdown content into manageable chunks based on headings and token limits, preserving context.
|
|
@@ -35,7 +36,13 @@ The primary goal is to prepare documentation content for Retrieval-Augmented Gen
|
|
|
35
36
|
* **Vector Storage:** Supports storing chunks, metadata, and embeddings in:
|
|
36
37
|
* **SQLite:** Using `better-sqlite3` and the `sqlite-vec` extension for efficient vector search.
|
|
37
38
|
* **Qdrant:** A dedicated vector database, using the `@qdrant/js-client-rest`.
|
|
38
|
-
* **Change Detection:**
|
|
39
|
+
* **Multi-Layer Change Detection:** Four layers of change detection minimize unnecessary re-processing:
|
|
40
|
+
1. **Sitemap `lastmod`:** When available, compares the sitemap's `<lastmod>` date against the stored value — skips without any HTTP request. Child URLs inherit `lastmod` from their most specific parent directory.
|
|
41
|
+
2. **ETag via HEAD request:** For URLs without `lastmod`, sends a lightweight HEAD request and compares the ETag header against the stored value. Adaptive backoff prevents rate limiting (starts at 0ms delay, increases on 429 responses, decays on success).
|
|
42
|
+
3. **Content hash comparison:** After full page load, compares chunk content hashes against stored values — skips embedding if content is unchanged.
|
|
43
|
+
4. **Embedding:** Only re-embeds chunks when content has actually changed.
|
|
44
|
+
|
|
45
|
+
ETag and lastmod values are only stored when chunking and embedding succeed, ensuring failed pages are retried on the next run.
|
|
39
46
|
* **Incremental Updates:** For GitHub and Zendesk sources, tracks the last run date to only fetch new or updated issues/tickets.
|
|
40
47
|
* **Cleanup:** Removes obsolete chunks from the database corresponding to pages or files that are no longer found during processing.
|
|
41
48
|
* **Configuration:** Driven by a YAML configuration file (`config.yaml`) specifying sites, repositories, local directories, Zendesk instances, database types, metadata, and other parameters.
|
|
@@ -496,12 +503,16 @@ If you don't specify a config path, it will look for config.yaml in the current
|
|
|
496
503
|
2. **Process by Source Type:**
|
|
497
504
|
- **For Websites:**
|
|
498
505
|
* Start at the base `url`.
|
|
499
|
-
* If `sitemap_url` is provided, fetch and parse the sitemap to extract
|
|
500
|
-
*
|
|
506
|
+
* If `sitemap_url` is provided, fetch and parse the sitemap to extract URLs and `lastmod` dates.
|
|
507
|
+
* Pre-seed the crawl queue with known URLs from the database (ensures link discovery isn't lost when pages are skipped).
|
|
508
|
+
* For each URL, apply multi-layer change detection:
|
|
509
|
+
1. If `lastmod` is available (from sitemap), compare against stored value — skip if unchanged.
|
|
510
|
+
2. Otherwise, send a HEAD request and compare the ETag — skip if unchanged. Adaptive backoff prevents rate limiting.
|
|
511
|
+
3. If no skip, use Puppeteer (`processPage`) to fetch and render the full page.
|
|
501
512
|
* For PDF URLs, download and extract text using Mozilla's PDF.js.
|
|
502
513
|
* Use Readability to extract main content from HTML pages.
|
|
503
514
|
* Sanitize HTML and convert to Markdown using Turndown.
|
|
504
|
-
*
|
|
515
|
+
* Discover links from the rendered DOM to add to the crawl queue.
|
|
505
516
|
* Keep track of all visited URLs.
|
|
506
517
|
- **For GitHub Repositories:**
|
|
507
518
|
* Fetch issues and comments using the GitHub API.
|
|
@@ -520,14 +531,63 @@ If you don't specify a config path, it will look for config.yaml in the current
|
|
|
520
531
|
* Track last run date to support incremental updates.
|
|
521
532
|
3. **Process Content:** For each processed page, issue, or file:
|
|
522
533
|
* **Chunk:** Split Markdown into smaller `DocumentChunk` objects based on headings and size.
|
|
523
|
-
* **
|
|
524
|
-
* **
|
|
525
|
-
* **
|
|
534
|
+
* **URL-Level Change Detection:** Compute content hashes for all new chunks and compare them against stored hashes for that URL. If all hashes match, the entire URL is skipped (no embedding or DB writes needed).
|
|
535
|
+
* **Re-process (if changed):** If any hash differs, delete all existing chunks for the URL and re-embed/insert all new chunks. This ensures consistent `chunk_index`/`total_chunks` values and eliminates orphaned chunks when content shifts (e.g., a paragraph is added in the middle).
|
|
536
|
+
* **Embed:** Call the OpenAI API (`createEmbeddings`) to get the vector embedding for each chunk.
|
|
537
|
+
* **Store:** Insert the chunk, metadata, hash, and embedding in the database (SQLite `vec_items` table or Qdrant collection).
|
|
526
538
|
4. **Cleanup:** After processing, remove any obsolete chunks from the database.
|
|
527
539
|
4. **Complete:** Log completion status.
|
|
528
540
|
|
|
529
541
|
## Recent Changes
|
|
530
542
|
|
|
543
|
+
### Multi-Layer Change Detection for Websites
|
|
544
|
+
- **Sitemap `lastmod` support:** When a sitemap includes `<lastmod>` dates, pages are skipped entirely if the date hasn't changed — no HEAD request, no Puppeteer load, no chunking. One sitemap fetch replaces hundreds of individual HEAD requests.
|
|
545
|
+
- **`lastmod` inheritance:** Child URLs without their own `<lastmod>` inherit from the most specific parent directory URL in the sitemap (e.g., `/docs/2.10.x/reference/cli/` inherits from `/docs/2.10.x/`).
|
|
546
|
+
- **ETag-based change detection:** For URLs not in the sitemap, a HEAD request compares the ETag header against the stored value. Pages with unchanged ETags are skipped without a full page load.
|
|
547
|
+
- **Adaptive HEAD request backoff:** Starts with no delay between HEAD requests. On 429 (rate limit), backs off starting at 200ms and doubles up to 5s. On success, the delay halves back toward zero. Prevents burst rate limiting while maximizing throughput.
|
|
548
|
+
- **Processing success gating:** ETag and lastmod values are only stored in metadata when chunking and embedding succeed. If processing fails, the next run will retry the page instead of incorrectly skipping it.
|
|
549
|
+
- **`parseSitemap` now returns a `Map<string, string | undefined>`** (URL → lastmod) instead of `string[]`, enabling lastmod data to flow through the pipeline.
|
|
550
|
+
- **`processPageContent` callback returns `boolean`** (true = success, false = failure) to signal whether metadata should be persisted.
|
|
551
|
+
|
|
552
|
+
### Puppeteer Resilience Improvements
|
|
553
|
+
- Browser restart escalation when protocol errors persist after page recreation
|
|
554
|
+
- Periodic browser restart every 50 pages to prevent memory accumulation
|
|
555
|
+
- Added `--disable-dev-shm-usage` Chrome flag (critical in Docker where `/dev/shm` defaults to 64MB)
|
|
556
|
+
- Added `--disable-gpu` and `--disable-extensions` flags
|
|
557
|
+
|
|
558
|
+
### HTTP 429 Retry for Full Page Processing
|
|
559
|
+
- Added `Retry-After` header parsing (supports seconds and HTTP-date formats)
|
|
560
|
+
- Per-URL retry tracking (max 3 attempts) with configurable delay (30s default, 120s cap)
|
|
561
|
+
- Queue re-insertion on retry to allow other URLs to be processed while waiting
|
|
562
|
+
|
|
563
|
+
### Qdrant Filter Fix
|
|
564
|
+
- Fixed `removeChunksByUrlQdrant` to use `match: { value: url }` (exact match) instead of `match: { text: url }` (full-text tokenized search), which was causing cross-URL chunk deletion
|
|
565
|
+
|
|
566
|
+
### URL Processing Fix
|
|
567
|
+
- Fixed `shouldProcessUrl` to return `true` for paths ending with `/`, preventing version-like URLs (e.g., `/app/2.1.x/`) from being incorrectly rejected by `path.extname`
|
|
568
|
+
|
|
569
|
+
### Tabbed Content Support
|
|
570
|
+
- Automatically detects tabbed UI components using the WAI-ARIA tabs pattern (`role="tab"` + `role="tabpanel"`)
|
|
571
|
+
- Injects tab labels (e.g., "Anthropic v1/messages", "OpenAI-compatible") as bold headings into each panel's content
|
|
572
|
+
- Makes hidden tab panels visible so all tab content is captured, not just the selected tab
|
|
573
|
+
- Handles pages with multiple tab groups that share the same panel IDs
|
|
574
|
+
- Falls back to positional matching when `aria-controls` attributes are missing
|
|
575
|
+
- Works in both the Puppeteer crawl pipeline and the standalone `convertHtmlToMarkdown` method
|
|
576
|
+
|
|
577
|
+
### URL-Level Change Detection
|
|
578
|
+
- Replaced per-chunk hash comparison with URL-level change detection across all source types (website, local directory, code, Zendesk)
|
|
579
|
+
- Computes content hashes for all chunks of a URL and compares them against stored hashes in a single DB query
|
|
580
|
+
- Unchanged URLs are skipped entirely (no embedding API calls, no DB writes)
|
|
581
|
+
- Changed URLs get all old chunks deleted and fresh chunks inserted with correct `chunk_index` and `total_chunks`
|
|
582
|
+
- Eliminates orphaned chunks and inconsistent metadata that occurred when content shifted (e.g., a paragraph added in the middle)
|
|
583
|
+
- Consolidated four duplicated chunk processing loops into a single shared `processChunksForUrl` method
|
|
584
|
+
|
|
585
|
+
### Puppeteer Resilience
|
|
586
|
+
- Added `protocolTimeout: 60000` to browser launch to fail faster on stuck protocol calls (down from default 180s)
|
|
587
|
+
- Added `evaluateWithTimeout` helper that wraps `page.evaluate` calls with a 30-second timeout to prevent indefinite hangs on pages with heavy/infinite JavaScript
|
|
588
|
+
- Added `about:blank` navigation between pages to clear lingering JavaScript, timers, WebSocket connections, and event listeners
|
|
589
|
+
- Added automatic page recreation after errors: when a page times out or errors, the next URL gets a fresh tab instead of reusing the potentially corrupted page
|
|
590
|
+
|
|
531
591
|
### Word Document Support
|
|
532
592
|
- Added support for legacy `.doc` files using the `word-extractor` library
|
|
533
593
|
- Added support for modern `.docx` files using the `mammoth` library
|