doc2vec 2.9.0 → 2.9.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.
- package/dist/content-processor.js +19 -18
- package/dist/doc2vec.js +4 -2
- package/package.json +1 -1
|
@@ -1707,7 +1707,10 @@ class ContentProcessor {
|
|
|
1707
1707
|
if (lang) {
|
|
1708
1708
|
try {
|
|
1709
1709
|
const codeChunker = await this.getCodeChunker(lang, sourceConfig.chunk_size);
|
|
1710
|
-
chunks = await
|
|
1710
|
+
chunks = await Promise.race([
|
|
1711
|
+
codeChunker.chunk(code),
|
|
1712
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`CodeChunker timed out after 30s for ${normalizedPath || url}`)), 30000))
|
|
1713
|
+
]);
|
|
1711
1714
|
}
|
|
1712
1715
|
catch (error) {
|
|
1713
1716
|
logger.warn(`CodeChunker failed for ${normalizedPath || url}, falling back to token chunking:`, error);
|
|
@@ -1757,9 +1760,9 @@ class ContentProcessor {
|
|
|
1757
1760
|
}
|
|
1758
1761
|
async chunkMarkdown(markdown, sourceConfig, url) {
|
|
1759
1762
|
const logger = this.logger.child('chunker');
|
|
1760
|
-
// --- Configuration ---
|
|
1761
|
-
const
|
|
1762
|
-
const
|
|
1763
|
+
// --- Configuration (character-based, ~4 chars ≈ 1 token) ---
|
|
1764
|
+
const MAX_CHARS = 4000;
|
|
1765
|
+
const MIN_CHARS = 600; // 💡 Merges short sections into the next block
|
|
1763
1766
|
const OVERLAP_PERCENT = 0.1; // 10% overlap for large splits
|
|
1764
1767
|
const chunks = [];
|
|
1765
1768
|
const lines = markdown.split("\n");
|
|
@@ -1821,29 +1824,27 @@ class ContentProcessor {
|
|
|
1821
1824
|
};
|
|
1822
1825
|
/**
|
|
1823
1826
|
* Flushes the current buffer into the chunks array.
|
|
1824
|
-
* Uses sub-splitting logic if the buffer exceeds
|
|
1827
|
+
* Uses sub-splitting logic if the buffer exceeds MAX_CHARS.
|
|
1825
1828
|
*/
|
|
1826
1829
|
const flushBuffer = (force = false) => {
|
|
1827
1830
|
const trimmedBuffer = buffer.trim();
|
|
1828
1831
|
if (!trimmedBuffer)
|
|
1829
1832
|
return;
|
|
1830
|
-
const
|
|
1833
|
+
const charCount = trimmedBuffer.length;
|
|
1831
1834
|
// 💡 SEMANTIC MERGING
|
|
1832
1835
|
// If the current section is too short (like just a title or a one-liner),
|
|
1833
1836
|
// we don't flush yet unless it's the end of the file (force=true).
|
|
1834
|
-
if (
|
|
1837
|
+
if (charCount < MIN_CHARS && !force) {
|
|
1835
1838
|
return;
|
|
1836
1839
|
}
|
|
1837
1840
|
// Compute the appropriate topic hierarchy for merged content
|
|
1838
1841
|
const topicHierarchy = computeTopicHierarchy();
|
|
1839
|
-
if (
|
|
1840
|
-
// 💡
|
|
1842
|
+
if (charCount > MAX_CHARS) {
|
|
1843
|
+
// 💡 OVERLAP SPLITTING
|
|
1841
1844
|
// If the section is a massive guide, split it but keep headers on every sub-piece.
|
|
1842
|
-
const
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
const subTokens = tokens.slice(i, i + MAX_TOKENS);
|
|
1846
|
-
const subContent = subTokens.join("");
|
|
1845
|
+
const overlapSize = Math.floor(MAX_CHARS * OVERLAP_PERCENT);
|
|
1846
|
+
for (let i = 0; i < trimmedBuffer.length; i += (MAX_CHARS - overlapSize)) {
|
|
1847
|
+
const subContent = trimmedBuffer.slice(i, i + MAX_CHARS);
|
|
1847
1848
|
chunks.push(createDocumentChunk(subContent, topicHierarchy));
|
|
1848
1849
|
}
|
|
1849
1850
|
}
|
|
@@ -1867,9 +1868,9 @@ class ContentProcessor {
|
|
|
1867
1868
|
.replace(/\[\]\(#[^)]*\)/g, "") // Remove [](#anchor) patterns
|
|
1868
1869
|
.trim();
|
|
1869
1870
|
// Check if we should merge with previous content
|
|
1870
|
-
const
|
|
1871
|
-
const hasBufferContent =
|
|
1872
|
-
const bufferIsSmall =
|
|
1871
|
+
const currentCharCount = buffer.trim().length;
|
|
1872
|
+
const hasBufferContent = currentCharCount > 0;
|
|
1873
|
+
const bufferIsSmall = currentCharCount < MIN_CHARS;
|
|
1873
1874
|
// Only merge if:
|
|
1874
1875
|
// 1. Buffer has content and is small
|
|
1875
1876
|
// 2. Buffer has tracked headings (we're merging sections, not just content)
|
|
@@ -1895,7 +1896,7 @@ class ContentProcessor {
|
|
|
1895
1896
|
else {
|
|
1896
1897
|
buffer += `${line}\n`;
|
|
1897
1898
|
// Safety valve: if a single section is huge, flush it periodically
|
|
1898
|
-
if (
|
|
1899
|
+
if (buffer.length >= MAX_CHARS) {
|
|
1899
1900
|
flushBuffer();
|
|
1900
1901
|
}
|
|
1901
1902
|
}
|
package/dist/doc2vec.js
CHANGED
|
@@ -1530,7 +1530,7 @@ class Doc2Vec {
|
|
|
1530
1530
|
const response = await this.openai.embeddings.create({
|
|
1531
1531
|
model: this.embeddingModel,
|
|
1532
1532
|
input: safeTexts,
|
|
1533
|
-
});
|
|
1533
|
+
}, { timeout: 60000 });
|
|
1534
1534
|
logger.debug(`Successfully created ${response.data.length} embeddings`);
|
|
1535
1535
|
return response.data.map(d => d.embedding);
|
|
1536
1536
|
}
|
|
@@ -1555,5 +1555,7 @@ if (require.main === module) {
|
|
|
1555
1555
|
process.exit(1);
|
|
1556
1556
|
}
|
|
1557
1557
|
const doc2Vec = new Doc2Vec(configPath);
|
|
1558
|
-
doc2Vec.run()
|
|
1558
|
+
doc2Vec.run()
|
|
1559
|
+
.then(() => process.exit(0))
|
|
1560
|
+
.catch((err) => { console.error(err); process.exit(1); });
|
|
1559
1561
|
}
|