doc2vec 1.2.0 → 2.0.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 CHANGED
@@ -2,31 +2,94 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/doc2vec.svg)](https://www.npmjs.com/package/doc2vec)
4
4
 
5
- This project provides a configurable tool (`doc2vec`) to crawl specified websites (typically documentation sites), GitHub repositories, and local directories, extract relevant content, convert it to Markdown, chunk it intelligently, generate vector embeddings using OpenAI, and store the chunks along with their embeddings in a vector database (SQLite with `sqlite-vec` or Qdrant).
5
+ This project provides a configurable tool (`doc2vec`) to crawl specified websites (typically documentation sites), GitHub repositories, local directories, and Zendesk support systems, extract relevant content, convert it to Markdown, chunk it intelligently, generate vector embeddings using OpenAI, and store the chunks along with their embeddings in a vector database (SQLite with `sqlite-vec` or Qdrant).
6
6
 
7
7
  The primary goal is to prepare documentation content for Retrieval-Augmented Generation (RAG) systems or semantic search applications.
8
8
 
9
+ > **⚠️ Version 2.0.0 Breaking Change:** Version 2.0.0 introduced enhanced chunking with new metadata fields (`chunk_index` and `total_chunks`) that enable page reconstruction and improved chunk ordering. The database schema has changed, and databases created with versions prior to 2.0.0 use a different format. **If you're upgrading to version 2.0.0 or later, you should start with fresh databases** to take advantage of the new features. While the MCP server maintains backward compatibility for querying old databases, doc2vec itself will create databases in the new format. If you need to migrate existing data, consider re-running doc2vec on your sources to regenerate the databases with the enhanced chunking format.
10
+
9
11
  ## Key Features
10
12
 
11
13
  * **Website Crawling:** Recursively crawls websites starting from a given base URL.
12
14
  * **Sitemap Support:** Extracts URLs from XML sitemaps to discover pages not linked in navigation.
13
15
  * **PDF Support:** Automatically downloads and processes PDF files linked from websites.
14
16
  * **GitHub Issues Integration:** Retrieves GitHub issues and comments, processing them into searchable chunks.
17
+ * **Zendesk Integration:** Fetches support tickets and knowledge base articles from Zendesk, converting them to searchable chunks.
18
+ * **Support Tickets:** Processes tickets with metadata, descriptions, and comments.
19
+ * **Knowledge Base Articles:** Converts help center articles from HTML to clean Markdown.
20
+ * **Incremental Updates:** Only processes tickets/articles updated since the last run.
21
+ * **Flexible Filtering:** Filter tickets by status and priority.
15
22
  * **Local Directory Processing:** Scans local directories for files, converts content to searchable chunks.
16
23
  * **PDF Support:** Automatically extracts text from PDF files and converts them to Markdown format using Mozilla's PDF.js.
24
+ * **Word Document Support:** Processes both legacy `.doc` and modern `.docx` files, extracting text and formatting.
17
25
  * **Content Extraction:** Uses Puppeteer for rendering JavaScript-heavy pages and `@mozilla/readability` to extract the main article content.
26
+ * **Smart H1 Preservation:** Automatically extracts and preserves page titles (H1 headings) that Readability might strip as "page chrome", ensuring proper heading hierarchy.
27
+ * **Flexible Content Selectors:** Supports multiple content container patterns (`.docs-content`, `.doc-content`, `.markdown-body`, `article`, etc.) for better compatibility with various documentation sites.
18
28
  * **HTML to Markdown:** Converts extracted HTML to clean Markdown using `turndown`, preserving code blocks and basic formatting.
29
+ * **Clean Heading Text:** Automatically removes anchor links (like `[](#section-id)`) from heading text for cleaner hierarchy display.
19
30
  * **Intelligent Chunking:** Splits Markdown content into manageable chunks based on headings and token limits, preserving context.
20
31
  * **Vector Embeddings:** Generates embeddings for each chunk using OpenAI's `text-embedding-3-large` model.
21
32
  * **Vector Storage:** Supports storing chunks, metadata, and embeddings in:
22
33
  * **SQLite:** Using `better-sqlite3` and the `sqlite-vec` extension for efficient vector search.
23
34
  * **Qdrant:** A dedicated vector database, using the `@qdrant/js-client-rest`.
24
35
  * **Change Detection:** Uses content hashing to detect changes and only re-embeds and updates chunks that have actually been modified.
25
- * **Incremental Updates:** For GitHub sources, tracks the last run date to only fetch new or updated issues.
36
+ * **Incremental Updates:** For GitHub and Zendesk sources, tracks the last run date to only fetch new or updated issues/tickets.
26
37
  * **Cleanup:** Removes obsolete chunks from the database corresponding to pages or files that are no longer found during processing.
27
- * **Configuration:** Driven by a YAML configuration file (`config.yaml`) specifying sites, repositories, local directories, database types, metadata, and other parameters.
38
+ * **Configuration:** Driven by a YAML configuration file (`config.yaml`) specifying sites, repositories, local directories, Zendesk instances, database types, metadata, and other parameters.
28
39
  * **Structured Logging:** Uses a custom logger (`logger.ts`) with levels, timestamps, colors, progress bars, and child loggers for clear execution monitoring.
29
40
 
41
+ ## Chunk Metadata & Page Reconstruction
42
+
43
+ Each chunk stored in the database includes rich metadata that enables powerful retrieval and page reconstruction capabilities.
44
+
45
+ ### Metadata Fields
46
+
47
+ | Field | Type | Description |
48
+ |-------|------|-------------|
49
+ | `product_name` | string | Product identifier from config |
50
+ | `version` | string | Version identifier from config |
51
+ | `heading_hierarchy` | string[] | Hierarchical breadcrumb trail (e.g., `["Installation", "Prerequisites", "Docker"]`) |
52
+ | `section` | string | Current section heading |
53
+ | `chunk_id` | string | Unique hash identifier for the chunk |
54
+ | `url` | string | Source URL/path of the original document |
55
+ | `hash` | string | Content hash for change detection |
56
+ | `chunk_index` | number | Position of this chunk within the page (0-based) |
57
+ | `total_chunks` | number | Total number of chunks for this page |
58
+
59
+ ### Page Reconstruction
60
+
61
+ The `chunk_index` and `total_chunks` fields enable you to reconstruct full pages from chunks:
62
+
63
+ ```typescript
64
+ // Example: Retrieve all chunks for a URL and reconstruct the page
65
+ const chunks = await db.query({
66
+ filter: { url: "https://docs.example.com/guide" },
67
+ sort: { chunk_index: "asc" }
68
+ });
69
+
70
+ // Check if there are more chunks after the current one
71
+ if (currentChunk.chunk_index < currentChunk.total_chunks - 1) {
72
+ // More chunks available - fetch the next one
73
+ const nextChunkIndex = currentChunk.chunk_index + 1;
74
+ }
75
+
76
+ // Reconstruct full page content
77
+ const fullPageContent = chunks
78
+ .sort((a, b) => a.chunk_index - b.chunk_index)
79
+ .map(c => c.content)
80
+ .join("\n\n");
81
+ ```
82
+
83
+ ### Heading Hierarchy (Breadcrumbs)
84
+
85
+ Each chunk includes a `heading_hierarchy` array that provides context about where the content appears in the document structure. This is injected as a `[Topic: ...]` prefix in the chunk content to improve vector search relevance.
86
+
87
+ For example, a chunk under "Installation > Prerequisites > Docker" will have:
88
+ - `heading_hierarchy`: `["Installation", "Prerequisites", "Docker"]`
89
+ - Content prefix: `[Topic: Installation > Prerequisites > Docker]`
90
+
91
+ This ensures that searches for parent topics (like "Installation") will also match relevant child content.
92
+
30
93
  ## Prerequisites
31
94
 
32
95
  * **Node.js:** Version 18 or higher recommended (check `.nvmrc` if available).
@@ -34,6 +97,7 @@ The primary goal is to prepare documentation content for Retrieval-Augmented Gen
34
97
  * **TypeScript:** As the project is written in TypeScript (`ts-node` is used for execution via `npm start`).
35
98
  * **OpenAI API Key:** You need an API key from OpenAI to generate embeddings.
36
99
  * **GitHub Personal Access Token:** Required for accessing GitHub issues (set as `GITHUB_PERSONAL_ACCESS_TOKEN` in your environment).
100
+ * **Zendesk API Token:** Required for accessing Zendesk tickets and articles (set as `ZENDESK_API_TOKEN` in your environment).
37
101
  * **(Optional) Qdrant Instance:** If using the `qdrant` database type, you need a running Qdrant instance accessible from where you run the script.
38
102
  * **(Optional) Build Tools:** Dependencies like `better-sqlite3` and `sqlite-vec` might require native compilation, which could necessitate build tools like `python`, `make`, and a C++ compiler (like `g++` or Clang) depending on your operating system.
39
103
 
@@ -68,6 +132,9 @@ Configuration is managed through two files:
68
132
  # Required for GitHub sources
69
133
  GITHUB_PERSONAL_ACCESS_TOKEN="ghp_..."
70
134
 
135
+ # Required for Zendesk sources
136
+ ZENDESK_API_TOKEN="your-zendesk-api-token"
137
+
71
138
  # Optional: Required only if using Qdrant
72
139
  QDRANT_API_KEY="your-qdrant-api-key"
73
140
  ```
@@ -78,7 +145,7 @@ Configuration is managed through two files:
78
145
  **Structure:**
79
146
 
80
147
  * `sources`: An array of source configurations.
81
- * `type`: Either `'website'`, `'github'`, or `'local_directory'`
148
+ * `type`: Either `'website'`, `'github'`, `'local_directory'`, or `'zendesk'`
82
149
 
83
150
  For websites (`type: 'website'`):
84
151
  * `url`: The starting URL for crawling the documentation site.
@@ -90,12 +157,22 @@ Configuration is managed through two files:
90
157
 
91
158
  For local directories (`type: 'local_directory'`):
92
159
  * `path`: Path to the local directory to process.
93
- * `include_extensions`: (Optional) Array of file extensions to include (e.g., `['.md', '.txt', '.pdf']`). Defaults to `['.md', '.txt', '.html', '.htm', '.pdf']`.
160
+ * `include_extensions`: (Optional) Array of file extensions to include (e.g., `['.md', '.txt', '.pdf', '.doc', '.docx']`). Defaults to `['.md', '.txt', '.html', '.htm', '.pdf']`.
94
161
  * `exclude_extensions`: (Optional) Array of file extensions to exclude.
95
162
  * `recursive`: (Optional) Whether to traverse subdirectories (defaults to `true`).
96
163
  * `url_rewrite_prefix` (Optional) URL prefix to rewrite `file://` URLs (e.g., `https://mydomain.com`)
97
164
  * `encoding`: (Optional) File encoding to use (defaults to `'utf8'`). Note: PDF files are processed as binary and this setting doesn't apply to them.
98
165
 
166
+ For Zendesk (`type: 'zendesk'`):
167
+ * `zendesk_subdomain`: Your Zendesk subdomain (e.g., `'mycompany'` for mycompany.zendesk.com).
168
+ * `email`: Your Zendesk admin email address.
169
+ * `api_token`: Your Zendesk API token (reference environment variable as `'${ZENDESK_API_TOKEN}'`).
170
+ * `fetch_tickets`: (Optional) Whether to fetch support tickets (defaults to `true`).
171
+ * `fetch_articles`: (Optional) Whether to fetch knowledge base articles (defaults to `true`).
172
+ * `start_date`: (Optional) Only process tickets/articles updated since this date (e.g., `'2025-01-01'`).
173
+ * `ticket_status`: (Optional) Filter tickets by status (defaults to `['new', 'open', 'pending', 'hold', 'solved']`).
174
+ * `ticket_priority`: (Optional) Filter tickets by priority (defaults to all priorities).
175
+
99
176
  Common configuration for all types:
100
177
  * `product_name`: A string identifying the product (used in metadata).
101
178
  * `version`: A string identifying the product version (used in metadata).
@@ -142,14 +219,32 @@ Configuration is managed through two files:
142
219
  product_name: 'project-docs'
143
220
  version: 'current'
144
221
  path: './docs'
145
- include_extensions: ['.md', '.txt', '.pdf']
222
+ include_extensions: ['.md', '.txt', '.pdf', '.doc', '.docx']
146
223
  recursive: true
147
- max_size: 10485760 # 10MB recommended for PDF files
224
+ max_size: 10485760 # 10MB recommended for PDF/Word files
148
225
  database_config:
149
226
  type: 'sqlite'
150
227
  params:
151
228
  db_path: './project-docs.db'
152
229
 
230
+ # Zendesk example
231
+ - type: 'zendesk'
232
+ product_name: 'MyCompany'
233
+ version: 'latest'
234
+ zendesk_subdomain: 'mycompany'
235
+ email: 'admin@mycompany.com'
236
+ api_token: '${ZENDESK_API_TOKEN}'
237
+ fetch_tickets: true
238
+ fetch_articles: true
239
+ start_date: '2025-01-01'
240
+ ticket_status: ['open', 'pending']
241
+ ticket_priority: ['high']
242
+ max_size: 1048576
243
+ database_config:
244
+ type: 'sqlite'
245
+ params:
246
+ db_path: './zendesk-kb.db'
247
+
153
248
  # Qdrant example
154
249
  - type: 'website'
155
250
  product_name: 'Istio'
@@ -188,6 +283,7 @@ The script will then:
188
283
  - For websites: Crawl the site, process any sitemaps, extract content from HTML pages and download/process PDF files, convert to Markdown
189
284
  - For GitHub repos: Fetch issues and comments, convert to Markdown
190
285
  - For local directories: Scan files, process content (converting HTML and PDF files to Markdown if needed)
286
+ - For Zendesk: Fetch tickets and articles, convert to Markdown
191
287
  6. For all sources: Chunk content, check for changes, generate embeddings (if needed), and store/update in the database.
192
288
  7. Cleanup obsolete chunks.
193
289
  8. Output detailed logs.
@@ -253,6 +349,67 @@ A PDF file named "user-guide.pdf" will be converted to Markdown format like:
253
349
 
254
350
  The resulting Markdown is then chunked and embedded using the same process as other text content.
255
351
 
352
+ ## Word Document Processing
353
+
354
+ Doc2Vec supports processing Microsoft Word documents in both legacy `.doc` format and modern `.docx` format.
355
+
356
+ ### Supported Formats
357
+
358
+ | Extension | Format | Library Used |
359
+ |-----------|--------|--------------|
360
+ | `.doc` | Legacy Word (97-2003) | [word-extractor](https://github.com/morungos/node-word-extractor) |
361
+ | `.docx` | Modern Word (2007+) | [mammoth](https://github.com/mwilliamson/mammoth.js) |
362
+
363
+ ### Features
364
+
365
+ * **Legacy .doc Support:** Extracts plain text from older Word documents using binary parsing
366
+ * **Modern .docx Support:** Converts DOCX files to HTML first (preserving formatting), then to clean Markdown
367
+ * **Formatting Preservation:** For `.docx` files, headings, lists, bold, italic, and links are preserved
368
+ * **Automatic Title:** Uses the filename as an H1 heading for proper document structure
369
+ * **Local File Support:** Processes Word files found in local directories alongside other documents
370
+
371
+ ### Configuration
372
+
373
+ Include `.doc` and/or `.docx` in your `include_extensions` array:
374
+
375
+ ```yaml
376
+ - type: 'local_directory'
377
+ product_name: 'company-docs'
378
+ version: 'current'
379
+ path: './documents'
380
+ include_extensions: ['.doc', '.docx', '.pdf', '.md']
381
+ recursive: true
382
+ max_size: 10485760 # 10MB recommended
383
+ database_config:
384
+ type: 'sqlite'
385
+ params:
386
+ db_path: './company-docs.db'
387
+ ```
388
+
389
+ ### Example Output
390
+
391
+ A Word document named "meeting-notes.docx" will be converted to Markdown like:
392
+
393
+ ```markdown
394
+ # meeting-notes
395
+
396
+ ## Agenda
397
+
398
+ 1. Review Q4 results
399
+ 2. Discuss roadmap
400
+
401
+ ## Action Items
402
+
403
+ - **John:** Prepare budget report
404
+ - **Sarah:** Schedule follow-up meeting
405
+ ```
406
+
407
+ ### Notes
408
+
409
+ * **`.doc` files:** Only plain text is extracted. Formatting like bold/italic is not preserved in legacy Word format.
410
+ * **`.docx` files:** Full formatting is preserved including headings, lists, bold, italic, links, and tables.
411
+ * **Embedded Images:** Images embedded in Word documents are not extracted (text-only).
412
+
256
413
  ## Now Available via npx
257
414
 
258
415
  You can run `doc2vec` without cloning the repo or installing it globally. Just use:
@@ -295,11 +452,46 @@ If you don't specify a config path, it will look for config.yaml in the current
295
452
  * Recursively scan directories for files matching the configured extensions.
296
453
  * Read file content, converting HTML to Markdown if needed.
297
454
  * For PDF files, extract text using Mozilla's PDF.js and convert to Markdown format with proper page structure.
455
+ * For Word documents, extract text from `.doc` files or convert `.docx` files to Markdown with formatting.
298
456
  * Process each file's content.
457
+ - **For Zendesk:**
458
+ * Fetch tickets and articles using the Zendesk API.
459
+ * Convert tickets to formatted Markdown.
460
+ * Convert articles to formatted Markdown.
461
+ * Track last run date to support incremental updates.
299
462
  3. **Process Content:** For each processed page, issue, or file:
300
463
  * **Chunk:** Split Markdown into smaller `DocumentChunk` objects based on headings and size.
301
464
  * **Hash Check:** Generate a hash of the chunk content. Check if a chunk with the same ID exists in the DB and if its hash matches.
302
465
  * **Embed (if needed):** If the chunk is new or changed, call the OpenAI API (`createEmbeddings`) to get the vector embedding.
303
466
  * **Store:** Insert or update the chunk, metadata, hash, and embedding in the database (SQLite `vec_items` table or Qdrant collection).
304
467
  4. **Cleanup:** After processing, remove any obsolete chunks from the database.
305
- 4. **Complete:** Log completion status.
468
+ 4. **Complete:** Log completion status.
469
+
470
+ ## Recent Changes
471
+
472
+ ### Word Document Support
473
+ - Added support for legacy `.doc` files using the `word-extractor` library
474
+ - Added support for modern `.docx` files using the `mammoth` library
475
+ - DOCX files preserve formatting (headings, lists, bold, italic, links)
476
+ - Both formats are converted to clean Markdown for embedding
477
+
478
+ ### Page Reconstruction Support
479
+ - Added `chunk_index` field to track each chunk's position within a page (0-based)
480
+ - Added `total_chunks` field to indicate the total number of chunks per page
481
+ - Enables AI agents and applications to fetch additional context or reconstruct full pages
482
+ - Works consistently across all content types: websites, GitHub, Zendesk, and local directories
483
+
484
+ ### Improved H1/Title Handling
485
+ - Smart H1 preservation ensures page titles aren't stripped by Readability
486
+ - Falls back to `article.title` when H1 extraction fails
487
+ - Proper heading hierarchy starting from H1 through the document structure
488
+
489
+ ### Enhanced Content Extraction
490
+ - Added support for multiple content container selectors (`.docs-content`, `.doc-content`, `.markdown-body`, `article`)
491
+ - Cleaner heading text by removing anchor links like `[](#section-id)`
492
+ - Better handling of pages where H1 is outside the main content container
493
+
494
+ ### Heading Hierarchy Improvements
495
+ - Fixed sparse array issues that caused `NULL` values in heading hierarchy
496
+ - Proper breadcrumb generation for nested sections
497
+ - Hierarchical context preserved across chunk boundaries