@ssmeo/mcp-local-rag 0.18.6
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 +21 -0
- package/README.de.md +441 -0
- package/README.es.md +441 -0
- package/README.fr.md +441 -0
- package/README.md +530 -0
- package/README.pt-BR.md +441 -0
- package/README.zh-CN.md +441 -0
- package/dist/bin/install-skills.d.ts +19 -0
- package/dist/bin/install-skills.d.ts.map +1 -0
- package/dist/bin/install-skills.js +218 -0
- package/dist/bin/install-skills.js.map +1 -0
- package/dist/chunker/index.d.ts +24 -0
- package/dist/chunker/index.d.ts.map +1 -0
- package/dist/chunker/index.js +2 -0
- package/dist/chunker/index.js.map +1 -0
- package/dist/chunker/semantic-chunker.d.ts +96 -0
- package/dist/chunker/semantic-chunker.d.ts.map +1 -0
- package/dist/chunker/semantic-chunker.js +362 -0
- package/dist/chunker/semantic-chunker.js.map +1 -0
- package/dist/chunker/sentence-splitter.d.ts +32 -0
- package/dist/chunker/sentence-splitter.d.ts.map +1 -0
- package/dist/chunker/sentence-splitter.js +231 -0
- package/dist/chunker/sentence-splitter.js.map +1 -0
- package/dist/chunker/token-containment.d.ts +39 -0
- package/dist/chunker/token-containment.d.ts.map +1 -0
- package/dist/chunker/token-containment.js +83 -0
- package/dist/chunker/token-containment.js.map +1 -0
- package/dist/cli/common.d.ts +34 -0
- package/dist/cli/common.d.ts.map +1 -0
- package/dist/cli/common.js +121 -0
- package/dist/cli/common.js.map +1 -0
- package/dist/cli/delete.d.ts +3 -0
- package/dist/cli/delete.d.ts.map +1 -0
- package/dist/cli/delete.js +169 -0
- package/dist/cli/delete.js.map +1 -0
- package/dist/cli/file-collection.d.ts +2 -0
- package/dist/cli/file-collection.d.ts.map +1 -0
- package/dist/cli/file-collection.js +53 -0
- package/dist/cli/file-collection.js.map +1 -0
- package/dist/cli/ingest.d.ts +69 -0
- package/dist/cli/ingest.d.ts.map +1 -0
- package/dist/cli/ingest.js +323 -0
- package/dist/cli/ingest.js.map +1 -0
- package/dist/cli/list.d.ts +27 -0
- package/dist/cli/list.d.ts.map +1 -0
- package/dist/cli/list.js +207 -0
- package/dist/cli/list.js.map +1 -0
- package/dist/cli/options.d.ts +89 -0
- package/dist/cli/options.d.ts.map +1 -0
- package/dist/cli/options.js +244 -0
- package/dist/cli/options.js.map +1 -0
- package/dist/cli/query.d.ts +17 -0
- package/dist/cli/query.d.ts.map +1 -0
- package/dist/cli/query.js +194 -0
- package/dist/cli/query.js.map +1 -0
- package/dist/cli/read-neighbors.d.ts +3 -0
- package/dist/cli/read-neighbors.d.ts.map +1 -0
- package/dist/cli/read-neighbors.js +192 -0
- package/dist/cli/read-neighbors.js.map +1 -0
- package/dist/cli/status.d.ts +6 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +78 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/sync.d.ts +6 -0
- package/dist/cli/sync.d.ts.map +1 -0
- package/dist/cli/sync.js +271 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/cli-main.d.ts +9 -0
- package/dist/cli-main.d.ts.map +1 -0
- package/dist/cli-main.js +60 -0
- package/dist/cli-main.js.map +1 -0
- package/dist/embedder/index.d.ts +143 -0
- package/dist/embedder/index.d.ts.map +1 -0
- package/dist/embedder/index.js +429 -0
- package/dist/embedder/index.js.map +1 -0
- package/dist/embedder/remote.d.ts +51 -0
- package/dist/embedder/remote.d.ts.map +1 -0
- package/dist/embedder/remote.js +182 -0
- package/dist/embedder/remote.js.map +1 -0
- package/dist/features/list.d.ts +37 -0
- package/dist/features/list.d.ts.map +1 -0
- package/dist/features/list.js +41 -0
- package/dist/features/list.js.map +1 -0
- package/dist/features/sync.d.ts +219 -0
- package/dist/features/sync.d.ts.map +1 -0
- package/dist/features/sync.js +461 -0
- package/dist/features/sync.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest/compute.d.ts +63 -0
- package/dist/ingest/compute.d.ts.map +1 -0
- package/dist/ingest/compute.js +161 -0
- package/dist/ingest/compute.js.map +1 -0
- package/dist/ingest/file.d.ts +40 -0
- package/dist/ingest/file.d.ts.map +1 -0
- package/dist/ingest/file.js +74 -0
- package/dist/ingest/file.js.map +1 -0
- package/dist/ingest/visual.d.ts +52 -0
- package/dist/ingest/visual.d.ts.map +1 -0
- package/dist/ingest/visual.js +294 -0
- package/dist/ingest/visual.js.map +1 -0
- package/dist/parser/docx-parser.d.ts +12 -0
- package/dist/parser/docx-parser.d.ts.map +1 -0
- package/dist/parser/docx-parser.js +375 -0
- package/dist/parser/docx-parser.js.map +1 -0
- package/dist/parser/html-parser.d.ts +16 -0
- package/dist/parser/html-parser.d.ts.map +1 -0
- package/dist/parser/html-parser.js +119 -0
- package/dist/parser/html-parser.js.map +1 -0
- package/dist/parser/index.d.ts +125 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +364 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/pdf-extract.d.ts +49 -0
- package/dist/parser/pdf-extract.d.ts.map +1 -0
- package/dist/parser/pdf-extract.js +114 -0
- package/dist/parser/pdf-extract.js.map +1 -0
- package/dist/parser/pdf-filter.d.ts +91 -0
- package/dist/parser/pdf-filter.d.ts.map +1 -0
- package/dist/parser/pdf-filter.js +522 -0
- package/dist/parser/pdf-filter.js.map +1 -0
- package/dist/parser/title-extractor.d.ts +28 -0
- package/dist/parser/title-extractor.d.ts.map +1 -0
- package/dist/parser/title-extractor.js +105 -0
- package/dist/parser/title-extractor.js.map +1 -0
- package/dist/pdf-visual/captioner.d.ts +11 -0
- package/dist/pdf-visual/captioner.d.ts.map +1 -0
- package/dist/pdf-visual/captioner.js +48 -0
- package/dist/pdf-visual/captioner.js.map +1 -0
- package/dist/pdf-visual/captioners/fast.d.ts +7 -0
- package/dist/pdf-visual/captioners/fast.d.ts.map +1 -0
- package/dist/pdf-visual/captioners/fast.js +108 -0
- package/dist/pdf-visual/captioners/fast.js.map +1 -0
- package/dist/pdf-visual/captioners/quality.d.ts +7 -0
- package/dist/pdf-visual/captioners/quality.d.ts.map +1 -0
- package/dist/pdf-visual/captioners/quality.js +101 -0
- package/dist/pdf-visual/captioners/quality.js.map +1 -0
- package/dist/pdf-visual/captioners/shared.d.ts +81 -0
- package/dist/pdf-visual/captioners/shared.d.ts.map +1 -0
- package/dist/pdf-visual/captioners/shared.js +156 -0
- package/dist/pdf-visual/captioners/shared.js.map +1 -0
- package/dist/pdf-visual/detector.d.ts +9 -0
- package/dist/pdf-visual/detector.d.ts.map +1 -0
- package/dist/pdf-visual/detector.js +269 -0
- package/dist/pdf-visual/detector.js.map +1 -0
- package/dist/pdf-visual/index.d.ts +13 -0
- package/dist/pdf-visual/index.d.ts.map +1 -0
- package/dist/pdf-visual/index.js +53 -0
- package/dist/pdf-visual/index.js.map +1 -0
- package/dist/pdf-visual/renderer.d.ts +9 -0
- package/dist/pdf-visual/renderer.d.ts.map +1 -0
- package/dist/pdf-visual/renderer.js +186 -0
- package/dist/pdf-visual/renderer.js.map +1 -0
- package/dist/pdf-visual/types.d.ts +53 -0
- package/dist/pdf-visual/types.d.ts.map +1 -0
- package/dist/pdf-visual/types.js +17 -0
- package/dist/pdf-visual/types.js.map +1 -0
- package/dist/server/error-utils.d.ts +63 -0
- package/dist/server/error-utils.d.ts.map +1 -0
- package/dist/server/error-utils.js +124 -0
- package/dist/server/error-utils.js.map +1 -0
- package/dist/server/index.d.ts +216 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +1068 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/list-scanner.d.ts +30 -0
- package/dist/server/list-scanner.d.ts.map +1 -0
- package/dist/server/list-scanner.js +50 -0
- package/dist/server/list-scanner.js.map +1 -0
- package/dist/server/tool-definitions.d.ts +8 -0
- package/dist/server/tool-definitions.d.ts.map +1 -0
- package/dist/server/tool-definitions.js +181 -0
- package/dist/server/tool-definitions.js.map +1 -0
- package/dist/server/tool-input.d.ts +37 -0
- package/dist/server/tool-input.d.ts.map +1 -0
- package/dist/server/tool-input.js +211 -0
- package/dist/server/tool-input.js.map +1 -0
- package/dist/server/types.d.ts +307 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +3 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server-main.d.ts +40 -0
- package/dist/server-main.d.ts.map +1 -0
- package/dist/server-main.js +254 -0
- package/dist/server-main.js.map +1 -0
- package/dist/utils/base-dirs.d.ts +145 -0
- package/dist/utils/base-dirs.d.ts.map +1 -0
- package/dist/utils/base-dirs.js +344 -0
- package/dist/utils/base-dirs.js.map +1 -0
- package/dist/utils/errors.d.ts +32 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +61 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/limits.d.ts +26 -0
- package/dist/utils/limits.d.ts.map +1 -0
- package/dist/utils/limits.js +28 -0
- package/dist/utils/limits.js.map +1 -0
- package/dist/utils/list-sources.d.ts +38 -0
- package/dist/utils/list-sources.d.ts.map +1 -0
- package/dist/utils/list-sources.js +40 -0
- package/dist/utils/list-sources.js.map +1 -0
- package/dist/utils/raw-data-utils.d.ts +76 -0
- package/dist/utils/raw-data-utils.d.ts.map +1 -0
- package/dist/utils/raw-data-utils.js +202 -0
- package/dist/utils/raw-data-utils.js.map +1 -0
- package/dist/utils/scan.d.ts +114 -0
- package/dist/utils/scan.d.ts.map +1 -0
- package/dist/utils/scan.js +209 -0
- package/dist/utils/scan.js.map +1 -0
- package/dist/utils/scope-match.d.ts +38 -0
- package/dist/utils/scope-match.d.ts.map +1 -0
- package/dist/utils/scope-match.js +86 -0
- package/dist/utils/scope-match.js.map +1 -0
- package/dist/utils/sensitive-path.d.ts +9 -0
- package/dist/utils/sensitive-path.d.ts.map +1 -0
- package/dist/utils/sensitive-path.js +78 -0
- package/dist/utils/sensitive-path.js.map +1 -0
- package/dist/utils/sync-path-key.d.ts +14 -0
- package/dist/utils/sync-path-key.d.ts.map +1 -0
- package/dist/utils/sync-path-key.js +27 -0
- package/dist/utils/sync-path-key.js.map +1 -0
- package/dist/utils/type-guards.d.ts +18 -0
- package/dist/utils/type-guards.d.ts.map +1 -0
- package/dist/utils/type-guards.js +34 -0
- package/dist/utils/type-guards.js.map +1 -0
- package/dist/utils/visual-profile.d.ts +10 -0
- package/dist/utils/visual-profile.d.ts.map +1 -0
- package/dist/utils/visual-profile.js +15 -0
- package/dist/utils/visual-profile.js.map +1 -0
- package/dist/vectordb/index.d.ts +132 -0
- package/dist/vectordb/index.d.ts.map +1 -0
- package/dist/vectordb/index.js +617 -0
- package/dist/vectordb/index.js.map +1 -0
- package/dist/vectordb/search-filters.d.ts +15 -0
- package/dist/vectordb/search-filters.d.ts.map +1 -0
- package/dist/vectordb/search-filters.js +129 -0
- package/dist/vectordb/search-filters.js.map +1 -0
- package/dist/vectordb/types.d.ts +194 -0
- package/dist/vectordb/types.d.ts.map +1 -0
- package/dist/vectordb/types.js +237 -0
- package/dist/vectordb/types.js.map +1 -0
- package/package.json +108 -0
- package/skills/mcp-local-rag/SKILL.md +234 -0
- package/skills/mcp-local-rag/references/cli-reference.md +190 -0
- package/skills/mcp-local-rag/references/html-ingestion.md +78 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
// Sentence Splitter for Semantic Chunking
|
|
2
|
+
// Created: 2025-12-27
|
|
3
|
+
// Purpose: Split text into sentences using Intl.Segmenter (Unicode standard)
|
|
4
|
+
// ============================================
|
|
5
|
+
// Constants
|
|
6
|
+
// ============================================
|
|
7
|
+
/**
|
|
8
|
+
* Placeholder for code blocks during processing
|
|
9
|
+
*/
|
|
10
|
+
const CODE_BLOCK_PLACEHOLDER = '\u0000CODE_BLOCK\u0000';
|
|
11
|
+
/**
|
|
12
|
+
* Placeholder for inline code during processing
|
|
13
|
+
*/
|
|
14
|
+
const INLINE_CODE_PLACEHOLDER = '\u0000INLINE_CODE\u0000';
|
|
15
|
+
// ============================================
|
|
16
|
+
// Helper Functions
|
|
17
|
+
// ============================================
|
|
18
|
+
function maskCode(text, sourceStart) {
|
|
19
|
+
const blocks = [];
|
|
20
|
+
const fenced = [...text.matchAll(/```[\s\S]*?```/g)].flatMap((match) => match.index === undefined ? [] : [{ start: match.index, end: match.index + match[0].length }]);
|
|
21
|
+
const matchedRanges = [...fenced];
|
|
22
|
+
let gapStart = 0;
|
|
23
|
+
for (const fencedRange of [...fenced, { start: text.length, end: text.length }]) {
|
|
24
|
+
const gap = text.slice(gapStart, fencedRange.start);
|
|
25
|
+
for (const match of gap.matchAll(/`[^`]+`/g)) {
|
|
26
|
+
if (match.index === undefined) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
matchedRanges.push({
|
|
30
|
+
start: gapStart + match.index,
|
|
31
|
+
end: gapStart + match.index + match[0].length,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
gapStart = fencedRange.end;
|
|
35
|
+
}
|
|
36
|
+
matchedRanges.sort((left, right) => left.start - right.start);
|
|
37
|
+
let mappedText = '';
|
|
38
|
+
let cursor = 0;
|
|
39
|
+
const segments = [];
|
|
40
|
+
const append = (value, start, end, linear) => {
|
|
41
|
+
const mappedStart = mappedText.length;
|
|
42
|
+
mappedText += value;
|
|
43
|
+
segments.push({
|
|
44
|
+
mappedStart,
|
|
45
|
+
mappedEnd: mappedText.length,
|
|
46
|
+
sourceStart: sourceStart + start,
|
|
47
|
+
sourceEnd: sourceStart + end,
|
|
48
|
+
linear,
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
for (const [index, range] of matchedRanges.entries()) {
|
|
52
|
+
if (range.start > cursor) {
|
|
53
|
+
append(text.slice(cursor, range.start), cursor, range.start, true);
|
|
54
|
+
}
|
|
55
|
+
const content = text.slice(range.start, range.end);
|
|
56
|
+
const placeholderPrefix = content.startsWith('```')
|
|
57
|
+
? CODE_BLOCK_PLACEHOLDER
|
|
58
|
+
: INLINE_CODE_PLACEHOLDER;
|
|
59
|
+
const placeholder = `${placeholderPrefix}${index}${placeholderPrefix}`;
|
|
60
|
+
blocks.push({ placeholder, content });
|
|
61
|
+
append(placeholder, range.start, range.end, false);
|
|
62
|
+
cursor = range.end;
|
|
63
|
+
}
|
|
64
|
+
if (cursor < text.length) {
|
|
65
|
+
append(text.slice(cursor), cursor, text.length, true);
|
|
66
|
+
}
|
|
67
|
+
return { mapped: { text: mappedText, segments }, blocks };
|
|
68
|
+
}
|
|
69
|
+
function sourceOffsetAt(mapped, offset, fallback) {
|
|
70
|
+
let low = 0;
|
|
71
|
+
let high = mapped.segments.length - 1;
|
|
72
|
+
while (low <= high) {
|
|
73
|
+
const middle = Math.floor((low + high) / 2);
|
|
74
|
+
const segment = mapped.segments[middle];
|
|
75
|
+
if (segment === undefined) {
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
if (offset < segment.mappedStart) {
|
|
79
|
+
high = middle - 1;
|
|
80
|
+
}
|
|
81
|
+
else if (offset > segment.mappedEnd) {
|
|
82
|
+
low = middle + 1;
|
|
83
|
+
}
|
|
84
|
+
else if (offset === segment.mappedEnd) {
|
|
85
|
+
return segment.sourceEnd;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
return segment.linear
|
|
89
|
+
? segment.sourceStart + (offset - segment.mappedStart)
|
|
90
|
+
: segment.sourceStart;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return fallback;
|
|
94
|
+
}
|
|
95
|
+
function restoreCode(text, blocks) {
|
|
96
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: NUL delimiters identify masked code placeholders.
|
|
97
|
+
const placeholderPattern = /(\u0000(?:CODE_BLOCK|INLINE_CODE)\u0000)(\d+)\1/g;
|
|
98
|
+
return text.replace(placeholderPattern, (placeholder, _prefix, index) => {
|
|
99
|
+
const block = blocks[Number(index)];
|
|
100
|
+
return block?.placeholder === placeholder ? block.content : placeholder;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function trimmedRange(text, start, end) {
|
|
104
|
+
const value = text.slice(start, end);
|
|
105
|
+
const trimmedStart = start + (value.length - value.trimStart().length);
|
|
106
|
+
const trimmedEnd = start + value.trimEnd().length;
|
|
107
|
+
return trimmedStart < trimmedEnd ? [trimmedStart, trimmedEnd] : null;
|
|
108
|
+
}
|
|
109
|
+
function splitOrdinaryRange(text, sourceStart, sourceEnd) {
|
|
110
|
+
if (sourceStart >= sourceEnd) {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
const { mapped, blocks } = maskCode(text.slice(sourceStart, sourceEnd), sourceStart);
|
|
114
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: NUL delimiters identify masked code placeholders.
|
|
115
|
+
const paragraphSeparator = /\n{2,}|\n(?=\S)|(?<=\u0000)\n/g;
|
|
116
|
+
const paragraphRanges = [];
|
|
117
|
+
let cursor = 0;
|
|
118
|
+
for (const match of mapped.text.matchAll(paragraphSeparator)) {
|
|
119
|
+
const separatorStart = match.index;
|
|
120
|
+
if (separatorStart === undefined) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
paragraphRanges.push([cursor, separatorStart]);
|
|
124
|
+
cursor = separatorStart + match[0].length;
|
|
125
|
+
}
|
|
126
|
+
paragraphRanges.push([cursor, mapped.text.length]);
|
|
127
|
+
const units = [];
|
|
128
|
+
const appendUnit = (start, end) => {
|
|
129
|
+
const range = trimmedRange(mapped.text, start, end);
|
|
130
|
+
if (!range) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const [trimmedStart, trimmedEnd] = range;
|
|
134
|
+
const restored = restoreCode(mapped.text.slice(trimmedStart, trimmedEnd), blocks).trim();
|
|
135
|
+
if (!restored) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
units.push({
|
|
139
|
+
text: restored,
|
|
140
|
+
atomic: false,
|
|
141
|
+
sourceStart: sourceOffsetAt(mapped, trimmedStart, sourceStart),
|
|
142
|
+
sourceEnd: sourceOffsetAt(mapped, trimmedEnd, sourceEnd),
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
for (const [paragraphStart, paragraphEnd] of paragraphRanges) {
|
|
146
|
+
const range = trimmedRange(mapped.text, paragraphStart, paragraphEnd);
|
|
147
|
+
if (!range) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
const [trimmedStart, trimmedEnd] = range;
|
|
151
|
+
const paragraph = mapped.text.slice(trimmedStart, trimmedEnd);
|
|
152
|
+
if (/^#{1,6}\s/.test(paragraph)) {
|
|
153
|
+
appendUnit(trimmedStart, trimmedEnd);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
for (const segment of segmenter.segment(paragraph)) {
|
|
157
|
+
appendUnit(trimmedStart + segment.index, trimmedStart + segment.index + segment.segment.length);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return units;
|
|
161
|
+
}
|
|
162
|
+
// ============================================
|
|
163
|
+
// Intl.Segmenter-based splitting
|
|
164
|
+
// ============================================
|
|
165
|
+
// Create segmenters for supported languages
|
|
166
|
+
// Using 'und' (undetermined) as fallback for general Unicode support
|
|
167
|
+
const segmenter = new Intl.Segmenter('und', { granularity: 'sentence' });
|
|
168
|
+
/**
|
|
169
|
+
* Split text into sentences using Intl.Segmenter
|
|
170
|
+
*
|
|
171
|
+
* Uses the Unicode Text Segmentation standard (UAX #29) via Intl.Segmenter.
|
|
172
|
+
* This provides multilingual support for sentence boundary detection.
|
|
173
|
+
*
|
|
174
|
+
* Note: Intl.Segmenter may split on abbreviations like "Mr." or "e.g."
|
|
175
|
+
* These edge cases are acceptable for semantic chunking as:
|
|
176
|
+
* 1. Short fragments will be grouped with adjacent sentences by similarity
|
|
177
|
+
* 2. Fragments below minChunkLength are filtered out
|
|
178
|
+
*/
|
|
179
|
+
export function splitIntoSentences(text) {
|
|
180
|
+
if (!text || text.trim().length === 0) {
|
|
181
|
+
return [];
|
|
182
|
+
}
|
|
183
|
+
return splitOrdinaryRange(text, 0, text.length).map((unit) => unit.text);
|
|
184
|
+
}
|
|
185
|
+
function validateAtomicRanges(text, atomicRanges) {
|
|
186
|
+
let previousEnd = 0;
|
|
187
|
+
for (const range of atomicRanges) {
|
|
188
|
+
const validOffsets = Number.isInteger(range.start) &&
|
|
189
|
+
Number.isInteger(range.end) &&
|
|
190
|
+
range.start >= 0 &&
|
|
191
|
+
range.start < range.end &&
|
|
192
|
+
range.end <= text.length;
|
|
193
|
+
const orderedAndNonOverlapping = range.start >= previousEnd;
|
|
194
|
+
if (!validOffsets || !orderedAndNonOverlapping) {
|
|
195
|
+
throw new Error(`Invalid atomic range [${range.start}, ${range.end}) for text length ${text.length}`);
|
|
196
|
+
}
|
|
197
|
+
previousEnd = range.end;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Split ordinary text while preserving the supplied positional ranges as
|
|
202
|
+
* indivisible sentence units.
|
|
203
|
+
*/
|
|
204
|
+
export function splitIntoSentenceUnits(text, atomicRanges = []) {
|
|
205
|
+
validateAtomicRanges(text, atomicRanges);
|
|
206
|
+
if (atomicRanges.length === 0) {
|
|
207
|
+
return splitOrdinaryRange(text, 0, text.length);
|
|
208
|
+
}
|
|
209
|
+
const units = [];
|
|
210
|
+
let cursor = 0;
|
|
211
|
+
for (const range of atomicRanges) {
|
|
212
|
+
units.push(...splitOrdinaryRange(text, cursor, range.start));
|
|
213
|
+
// Offsets advance with the trim so the text stays the exact source slice
|
|
214
|
+
// that source-position arithmetic relies on.
|
|
215
|
+
const atomicRange = trimmedRange(text, range.start, range.end);
|
|
216
|
+
if (!atomicRange) {
|
|
217
|
+
throw new Error(`Invalid atomic range [${range.start}, ${range.end}): empty text`);
|
|
218
|
+
}
|
|
219
|
+
const [atomicStart, atomicEnd] = atomicRange;
|
|
220
|
+
units.push({
|
|
221
|
+
text: text.slice(atomicStart, atomicEnd),
|
|
222
|
+
atomic: true,
|
|
223
|
+
sourceStart: atomicStart,
|
|
224
|
+
sourceEnd: atomicEnd,
|
|
225
|
+
});
|
|
226
|
+
cursor = range.end;
|
|
227
|
+
}
|
|
228
|
+
units.push(...splitOrdinaryRange(text, cursor, text.length));
|
|
229
|
+
return units;
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=sentence-splitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sentence-splitter.js","sourceRoot":"","sources":["../../src/chunker/sentence-splitter.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,sBAAsB;AACtB,6EAA6E;AAI7E,+CAA+C;AAC/C,YAAY;AACZ,+CAA+C;AAE/C;;GAEG;AACH,MAAM,sBAAsB,GAAG,wBAAwB,CAAA;AAEvD;;GAEG;AACH,MAAM,uBAAuB,GAAG,yBAAyB,CAAA;AAsCzD,+CAA+C;AAC/C,mBAAmB;AACnB,+CAA+C;AAE/C,SAAS,QAAQ,CACf,IAAY,EACZ,WAAmB;IAEnB,MAAM,MAAM,GAAoB,EAAE,CAAA;IAClC,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CACrE,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAC9F,CAAA;IACD,MAAM,aAAa,GAAG,CAAC,GAAG,MAAM,CAAC,CAAA;IACjC,IAAI,QAAQ,GAAG,CAAC,CAAA;IAChB,KAAK,MAAM,WAAW,IAAI,CAAC,GAAG,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;QAChF,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,CAAA;QACnD,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7C,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC9B,SAAQ;YACV,CAAC;YACD,aAAa,CAAC,IAAI,CAAC;gBACjB,KAAK,EAAE,QAAQ,GAAG,KAAK,CAAC,KAAK;gBAC7B,GAAG,EAAE,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM;aAC9C,CAAC,CAAA;QACJ,CAAC;QACD,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAA;IAC5B,CAAC;IACD,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;IAE7D,IAAI,UAAU,GAAG,EAAE,CAAA;IACnB,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,MAAM,QAAQ,GAAqB,EAAE,CAAA;IACrC,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,KAAa,EAAE,GAAW,EAAE,MAAe,EAAQ,EAAE;QAClF,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAA;QACrC,UAAU,IAAI,KAAK,CAAA;QACnB,QAAQ,CAAC,IAAI,CAAC;YACZ,WAAW;YACX,SAAS,EAAE,UAAU,CAAC,MAAM;YAC5B,WAAW,EAAE,WAAW,GAAG,KAAK;YAChC,SAAS,EAAE,WAAW,GAAG,GAAG;YAC5B,MAAM;SACP,CAAC,CAAA;IACJ,CAAC,CAAA;IACD,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC;QACrD,IAAI,KAAK,CAAC,KAAK,GAAG,MAAM,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QACpE,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;QAClD,MAAM,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC;YACjD,CAAC,CAAC,sBAAsB;YACxB,CAAC,CAAC,uBAAuB,CAAA;QAC3B,MAAM,WAAW,GAAG,GAAG,iBAAiB,GAAG,KAAK,GAAG,iBAAiB,EAAE,CAAA;QACtE,MAAM,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAA;QACrC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QAClD,MAAM,GAAG,KAAK,CAAC,GAAG,CAAA;IACpB,CAAC;IACD,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACvD,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAA;AAC3D,CAAC;AAED,SAAS,cAAc,CAAC,MAAkB,EAAE,MAAc,EAAE,QAAgB;IAC1E,IAAI,GAAG,GAAG,CAAC,CAAA;IACX,IAAI,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAA;IACrC,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QAC3C,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;QACvC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAK;QACP,CAAC;QACD,IAAI,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;YACjC,IAAI,GAAG,MAAM,GAAG,CAAC,CAAA;QACnB,CAAC;aAAM,IAAI,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;YACtC,GAAG,GAAG,MAAM,GAAG,CAAC,CAAA;QAClB,CAAC;aAAM,IAAI,MAAM,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;YACxC,OAAO,OAAO,CAAC,SAAS,CAAA;QAC1B,CAAC;aAAM,CAAC;YACN,OAAO,OAAO,CAAC,MAAM;gBACnB,CAAC,CAAC,OAAO,CAAC,WAAW,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;gBACtD,CAAC,CAAC,OAAO,CAAC,WAAW,CAAA;QACzB,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,MAAuB;IACxD,6GAA6G;IAC7G,MAAM,kBAAkB,GAAG,kDAAkD,CAAA;IAC7E,OAAO,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,KAAa,EAAE,EAAE;QAC9E,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QACnC,OAAO,KAAK,EAAE,WAAW,KAAK,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAA;IACzE,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,IAAY,EAAE,KAAa,EAAE,GAAW;IAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACpC,MAAM,YAAY,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,CAAA;IACtE,MAAM,UAAU,GAAG,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,MAAM,CAAA;IACjD,OAAO,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AACtE,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY,EAAE,WAAmB,EAAE,SAAiB;IAC9E,IAAI,WAAW,IAAI,SAAS,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAA;IACX,CAAC;IACD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,WAAW,CAAC,CAAA;IACpF,6GAA6G;IAC7G,MAAM,kBAAkB,GAAG,gCAAgC,CAAA;IAC3D,MAAM,eAAe,GAA4B,EAAE,CAAA;IACnD,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC7D,MAAM,cAAc,GAAG,KAAK,CAAC,KAAK,CAAA;QAClC,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YACjC,SAAQ;QACV,CAAC;QACD,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAA;QAC9C,MAAM,GAAG,cAAc,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;IAC3C,CAAC;IACD,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;IAElD,MAAM,KAAK,GAAmB,EAAE,CAAA;IAChC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,GAAW,EAAQ,EAAE;QACtD,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;QACnD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAM;QACR,CAAC;QACD,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,GAAG,KAAK,CAAA;QACxC,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;QACxF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAM;QACR,CAAC;QACD,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,KAAK;YACb,WAAW,EAAE,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,CAAC;YAC9D,SAAS,EAAE,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC;SACzD,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,KAAK,MAAM,CAAC,cAAc,EAAE,YAAY,CAAC,IAAI,eAAe,EAAE,CAAC;QAC7D,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,EAAE,YAAY,CAAC,CAAA;QACrE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,SAAQ;QACV,CAAC;QACD,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,GAAG,KAAK,CAAA;QACxC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;QAC7D,IAAI,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,UAAU,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;YACpC,SAAQ;QACV,CAAC;QACD,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YACnD,UAAU,CACR,YAAY,GAAG,OAAO,CAAC,KAAK,EAC5B,YAAY,GAAG,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CACtD,CAAA;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,+CAA+C;AAC/C,iCAAiC;AACjC,+CAA+C;AAE/C,4CAA4C;AAC5C,qEAAqE;AACrE,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAA;AAExE;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,CAAA;IACX,CAAC;IACD,OAAO,kBAAkB,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC1E,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAY,EAAE,YAAwC;IAClF,IAAI,WAAW,GAAG,CAAC,CAAA;IAEnB,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QACjC,MAAM,YAAY,GAChB,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC;YAC7B,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC;YAC3B,KAAK,CAAC,KAAK,IAAI,CAAC;YAChB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG;YACvB,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,MAAM,CAAA;QAC1B,MAAM,wBAAwB,GAAG,KAAK,CAAC,KAAK,IAAI,WAAW,CAAA;QAE3D,IAAI,CAAC,YAAY,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CACb,yBAAyB,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,GAAG,qBAAqB,IAAI,CAAC,MAAM,EAAE,CACrF,CAAA;QACH,CAAC;QACD,WAAW,GAAG,KAAK,CAAC,GAAG,CAAA;IACzB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAY,EACZ,YAAY,GAA+B,EAAE;IAE7C,oBAAoB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;IACxC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,kBAAkB,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IACjD,CAAC;IAED,MAAM,KAAK,GAAmB,EAAE,CAAA;IAChC,IAAI,MAAM,GAAG,CAAC,CAAA;IAEd,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;QAC5D,yEAAyE;QACzE,6CAA6C;QAC7C,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;QAC9D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,GAAG,eAAe,CAAC,CAAA;QACpF,CAAC;QACD,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,GAAG,WAAW,CAAA;QAC5C,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC;YACxC,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,WAAW;YACxB,SAAS,EAAE,SAAS;SACrB,CAAC,CAAA;QACF,MAAM,GAAG,KAAK,CAAC,GAAG,CAAA;IACpB,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;IAE5D,OAAO,KAAK,CAAA;AACd,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** Measures true, unclamped token lengths for each input text. */
|
|
2
|
+
export type TokenCounter = (texts: string[]) => Promise<number[]>;
|
|
3
|
+
/** The unit shape containment reads. `text` must be the exact slice `[sourceStart, sourceEnd)`. */
|
|
4
|
+
export interface ContainmentUnit {
|
|
5
|
+
text: string;
|
|
6
|
+
sourceStart: number;
|
|
7
|
+
sourceEnd: number;
|
|
8
|
+
}
|
|
9
|
+
export interface ContainmentBudget {
|
|
10
|
+
/** Resolved token cap: a piece measuring at or below it fits the model's window. */
|
|
11
|
+
cap: number;
|
|
12
|
+
countTokens: TokenCounter;
|
|
13
|
+
}
|
|
14
|
+
export interface RunContainmentBudget<T> extends ContainmentBudget {
|
|
15
|
+
/**
|
|
16
|
+
* Joins a run exactly as the chunk text is built, so the measured text is the
|
|
17
|
+
* text that will be embedded.
|
|
18
|
+
*/
|
|
19
|
+
joinUnits: (units: readonly T[]) => string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Divide one sentence unit into pieces that each measure at or below the cap.
|
|
23
|
+
*
|
|
24
|
+
* Halving, not a search for the longest fitting prefix: token count is not
|
|
25
|
+
* monotonic in prefix length — the prefixes of `playingx` measure 3, 3, 4, 3,
|
|
26
|
+
* 4, 4, 3, 4 here. A single grapheme over the cap is emitted anyway, leaving
|
|
27
|
+
* the embedder's clamp to truncate it.
|
|
28
|
+
*/
|
|
29
|
+
export declare function splitUnitToFit<T extends ContainmentUnit>(unit: T, budget: ContainmentBudget): Promise<T[]>;
|
|
30
|
+
/**
|
|
31
|
+
* Divide a group into consecutive runs of whole units whose joined text measures
|
|
32
|
+
* at or below the cap.
|
|
33
|
+
*
|
|
34
|
+
* A one-unit run is final even above the cap: {@link splitUnitToFit} already
|
|
35
|
+
* reduced that unit as far as a valid cut allows. Each division strictly reduces
|
|
36
|
+
* the units per run, so progress does not depend on the text.
|
|
37
|
+
*/
|
|
38
|
+
export declare function splitUnitsIntoFittingRuns<T>(units: readonly T[], budget: RunContainmentBudget<T>): Promise<T[][]>;
|
|
39
|
+
//# sourceMappingURL=token-containment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-containment.d.ts","sourceRoot":"","sources":["../../src/chunker/token-containment.ts"],"names":[],"mappings":"AAGA,kEAAkE;AAClE,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;AAEjE,mGAAmG;AACnG,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,oFAAoF;IACpF,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,YAAY,CAAA;CAC1B;AAED,MAAM,WAAW,oBAAoB,CAAC,CAAC,CAAE,SAAQ,iBAAiB;IAChE;;;OAGG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,MAAM,CAAA;CAC3C;AA2BD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,CAAC,SAAS,eAAe,EAC5D,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,CAAC,EAAE,CAAC,CA8Bd;AAED;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAAC,CAAC,EAC/C,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAC9B,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAehB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Reduces oversized sentence units and groups to pieces that measure at or below
|
|
2
|
+
// the embedder's resolved token cap, cutting only at grapheme boundaries.
|
|
3
|
+
/**
|
|
4
|
+
* Cuts land on grapheme boundaries: a string index addresses a UTF-16 code unit,
|
|
5
|
+
* so an unconstrained cut can leave a lone surrogate ('\u{20000}'.length === 2)
|
|
6
|
+
* or split a base character from its combining marks.
|
|
7
|
+
*/
|
|
8
|
+
const graphemeSegmenter = new Intl.Segmenter('und', { granularity: 'grapheme' });
|
|
9
|
+
/** Grapheme boundary offsets in `text`, terminated by `text.length`. */
|
|
10
|
+
function graphemeBoundaries(text) {
|
|
11
|
+
const boundaries = [];
|
|
12
|
+
for (const segment of graphemeSegmenter.segment(text)) {
|
|
13
|
+
boundaries.push(segment.index);
|
|
14
|
+
}
|
|
15
|
+
boundaries.push(text.length);
|
|
16
|
+
return boundaries;
|
|
17
|
+
}
|
|
18
|
+
async function measure(text, budget) {
|
|
19
|
+
const [tokens] = await budget.countTokens([text]);
|
|
20
|
+
if (tokens === undefined) {
|
|
21
|
+
throw new Error('Token counter returned no measurement for the requested text');
|
|
22
|
+
}
|
|
23
|
+
return tokens;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Divide one sentence unit into pieces that each measure at or below the cap.
|
|
27
|
+
*
|
|
28
|
+
* Halving, not a search for the longest fitting prefix: token count is not
|
|
29
|
+
* monotonic in prefix length — the prefixes of `playingx` measure 3, 3, 4, 3,
|
|
30
|
+
* 4, 4, 3, 4 here. A single grapheme over the cap is emitted anyway, leaving
|
|
31
|
+
* the embedder's clamp to truncate it.
|
|
32
|
+
*/
|
|
33
|
+
export async function splitUnitToFit(unit, budget) {
|
|
34
|
+
const boundaries = graphemeBoundaries(unit.text);
|
|
35
|
+
const graphemeCount = boundaries.length - 1;
|
|
36
|
+
const pieces = [];
|
|
37
|
+
let start = 0;
|
|
38
|
+
let nextCandidate = budget.cap;
|
|
39
|
+
while (start < graphemeCount) {
|
|
40
|
+
const pieceStart = boundaries[start] ?? 0;
|
|
41
|
+
const measureCandidate = (size) => measure(unit.text.slice(pieceStart, boundaries[start + size] ?? unit.text.length), budget);
|
|
42
|
+
let candidate = Math.min(graphemeCount - start, nextCandidate);
|
|
43
|
+
let tokens = await measureCandidate(candidate);
|
|
44
|
+
while (tokens > budget.cap && candidate > 1) {
|
|
45
|
+
candidate = Math.floor(candidate / 2);
|
|
46
|
+
tokens = await measureCandidate(candidate);
|
|
47
|
+
}
|
|
48
|
+
nextCandidate = candidate * 2;
|
|
49
|
+
const pieceEnd = boundaries[start + candidate] ?? unit.text.length;
|
|
50
|
+
pieces.push({
|
|
51
|
+
...unit,
|
|
52
|
+
text: unit.text.slice(pieceStart, pieceEnd),
|
|
53
|
+
sourceStart: unit.sourceStart + pieceStart,
|
|
54
|
+
sourceEnd: unit.sourceStart + pieceEnd,
|
|
55
|
+
});
|
|
56
|
+
start += candidate;
|
|
57
|
+
}
|
|
58
|
+
return pieces;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Divide a group into consecutive runs of whole units whose joined text measures
|
|
62
|
+
* at or below the cap.
|
|
63
|
+
*
|
|
64
|
+
* A one-unit run is final even above the cap: {@link splitUnitToFit} already
|
|
65
|
+
* reduced that unit as far as a valid cut allows. Each division strictly reduces
|
|
66
|
+
* the units per run, so progress does not depend on the text.
|
|
67
|
+
*/
|
|
68
|
+
export async function splitUnitsIntoFittingRuns(units, budget) {
|
|
69
|
+
if (units.length === 0) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
if (units.length === 1) {
|
|
73
|
+
return [[...units]];
|
|
74
|
+
}
|
|
75
|
+
if ((await measure(budget.joinUnits(units), budget)) <= budget.cap) {
|
|
76
|
+
return [[...units]];
|
|
77
|
+
}
|
|
78
|
+
const mid = Math.ceil(units.length / 2);
|
|
79
|
+
const head = await splitUnitsIntoFittingRuns(units.slice(0, mid), budget);
|
|
80
|
+
const tail = await splitUnitsIntoFittingRuns(units.slice(mid), budget);
|
|
81
|
+
return [...head, ...tail];
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=token-containment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-containment.js","sourceRoot":"","sources":["../../src/chunker/token-containment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Embedder } from '../embedder/index.js';
|
|
2
|
+
import { RemoteEmbedder } from '../embedder/remote.js';
|
|
3
|
+
import { type BaseDirsConfig, type BaseDirsConfigWarning } from '../utils/base-dirs.js';
|
|
4
|
+
import { VectorStore } from '../vectordb/index.js';
|
|
5
|
+
import { type ResolvedGlobalConfig } from './options.js';
|
|
6
|
+
/**
|
|
7
|
+
* Render a caught value for a CLI failure: every `.cause` link with its stack,
|
|
8
|
+
* deeper links prefixed `Caused by: `.
|
|
9
|
+
*
|
|
10
|
+
* The CLI is operator-facing, so unlike the MCP boundary the full chain IS
|
|
11
|
+
* printed. Callers keep their own prefix and exit-code policy.
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatCliError(error: unknown): string;
|
|
14
|
+
/**
|
|
15
|
+
* Create an uninitialized VectorStore from resolved global config.
|
|
16
|
+
* Callers are responsible for calling initialize() before use.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createVectorStore(config: ResolvedGlobalConfig): VectorStore;
|
|
19
|
+
/**
|
|
20
|
+
* Create an uninitialized Embedder from resolved global config.
|
|
21
|
+
* Callers are responsible for managing the Embedder lifecycle.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createEmbedder(config: ResolvedGlobalConfig): Embedder | RemoteEmbedder;
|
|
24
|
+
/**
|
|
25
|
+
* Result of {@link resolveCliBaseDirsOrExit}. Resolution warnings travel with
|
|
26
|
+
* the config so subcommands can render them per their own UI contract (CLI
|
|
27
|
+
* subcommands generally write them to stderr).
|
|
28
|
+
*/
|
|
29
|
+
export interface CliBaseDirsResolution {
|
|
30
|
+
config: BaseDirsConfig;
|
|
31
|
+
warnings: BaseDirsConfigWarning[];
|
|
32
|
+
}
|
|
33
|
+
export declare function resolveCliBaseDirsOrExit(cliRoots: string[]): Promise<CliBaseDirsResolution>;
|
|
34
|
+
//# sourceMappingURL=common.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/cli/common.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAG3B,MAAM,uBAAuB,CAAA;AAG9B,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EACL,KAAK,oBAAoB,EAK1B,MAAM,cAAc,CAAA;AAErB;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQrD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,oBAAoB,GAAG,WAAW,CAK3E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,QAAQ,GAAG,cAAc,CAmBtF;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,cAAc,CAAA;IACtB,QAAQ,EAAE,qBAAqB,EAAE,CAAA;CAClC;AA6CD,wBAAsB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA2BjG"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Shared CLI component helpers — factory functions for VectorStore and Embedder
|
|
2
|
+
// plus base-directory resolution shared by every subcommand that scans files.
|
|
3
|
+
import { Embedder } from '../embedder/index.js';
|
|
4
|
+
import { RemoteEmbedder } from '../embedder/remote.js';
|
|
5
|
+
import { parseBaseDirsEnv, resolveBaseDirs, } from '../utils/base-dirs.js';
|
|
6
|
+
import { getCauseChain } from '../utils/errors.js';
|
|
7
|
+
import { checkSensitivePath } from '../utils/sensitive-path.js';
|
|
8
|
+
import { VectorStore } from '../vectordb/index.js';
|
|
9
|
+
import { resolveDevice, resolveDtype, resolveEmbeddingServerUrl, validatePath, } from './options.js';
|
|
10
|
+
/**
|
|
11
|
+
* Render a caught value for a CLI failure: every `.cause` link with its stack,
|
|
12
|
+
* deeper links prefixed `Caused by: `.
|
|
13
|
+
*
|
|
14
|
+
* The CLI is operator-facing, so unlike the MCP boundary the full chain IS
|
|
15
|
+
* printed. Callers keep their own prefix and exit-code policy.
|
|
16
|
+
*/
|
|
17
|
+
export function formatCliError(error) {
|
|
18
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
19
|
+
return getCauseChain(err)
|
|
20
|
+
.map((link, index) => {
|
|
21
|
+
const header = index === 0 ? '' : 'Caused by: ';
|
|
22
|
+
return `${header}${link.stack || `${link.name}: ${link.message}`}`;
|
|
23
|
+
})
|
|
24
|
+
.join('\n');
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Create an uninitialized VectorStore from resolved global config.
|
|
28
|
+
* Callers are responsible for calling initialize() before use.
|
|
29
|
+
*/
|
|
30
|
+
export function createVectorStore(config) {
|
|
31
|
+
return new VectorStore({
|
|
32
|
+
dbPath: config.dbPath,
|
|
33
|
+
tableName: 'chunks',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Create an uninitialized Embedder from resolved global config.
|
|
38
|
+
* Callers are responsible for managing the Embedder lifecycle.
|
|
39
|
+
*/
|
|
40
|
+
export function createEmbedder(config) {
|
|
41
|
+
const serverUrl = resolveEmbeddingServerUrl(process.env['RAG_EMBEDDING_SERVER_URL']);
|
|
42
|
+
if (serverUrl) {
|
|
43
|
+
return new RemoteEmbedder({ serverUrl, batchSize: 16 });
|
|
44
|
+
}
|
|
45
|
+
const embedderConfig = {
|
|
46
|
+
modelPath: config.modelName,
|
|
47
|
+
batchSize: 16,
|
|
48
|
+
cacheDir: config.cacheDir,
|
|
49
|
+
device: resolveDevice(process.env['RAG_DEVICE']),
|
|
50
|
+
};
|
|
51
|
+
// Set dtype only when RAG_DTYPE resolves to a defined value, mirroring the
|
|
52
|
+
// server path — an unset RAG_DTYPE leaves config.dtype undefined so the
|
|
53
|
+
// embedder applies its fp32 default.
|
|
54
|
+
const dtype = resolveDtype(process.env['RAG_DTYPE']);
|
|
55
|
+
if (dtype !== undefined) {
|
|
56
|
+
embedderConfig.dtype = dtype;
|
|
57
|
+
}
|
|
58
|
+
return new Embedder(embedderConfig);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Resolve base directories for a CLI subcommand: `cliRoots` replaces the env
|
|
62
|
+
* roots rather than merging, and a config error exits 1 rather than falling
|
|
63
|
+
* back to cwd.
|
|
64
|
+
*
|
|
65
|
+
* Warnings are returned, not printed, so a JSON-output subcommand can keep
|
|
66
|
+
* stderr clean.
|
|
67
|
+
*/
|
|
68
|
+
/** Report the first sensitive root among `roots` and stop. */
|
|
69
|
+
function exitOnSensitiveRoot(roots, check, flag) {
|
|
70
|
+
for (const root of roots) {
|
|
71
|
+
const sensitive = check(root, flag);
|
|
72
|
+
if (sensitive) {
|
|
73
|
+
console.error(sensitive);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Screen the raw env-supplied roots before the resolver realpath-normalizes
|
|
80
|
+
* them, so a literal `BASE_DIR=/etc` is rejected with the env var as the
|
|
81
|
+
* attribution surface. Malformed `BASE_DIRS` surfaces later via resolveBaseDirs.
|
|
82
|
+
*/
|
|
83
|
+
function exitOnSensitiveEnvRoots() {
|
|
84
|
+
const baseDirs = process.env['BASE_DIRS'];
|
|
85
|
+
if (baseDirs !== undefined && baseDirs.length > 0) {
|
|
86
|
+
const parsed = parseBaseDirsEnv(baseDirs);
|
|
87
|
+
if (parsed.ok) {
|
|
88
|
+
exitOnSensitiveRoot(parsed.value, checkSensitivePath, 'BASE_DIRS');
|
|
89
|
+
}
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const baseDir = process.env['BASE_DIR'];
|
|
93
|
+
if (baseDir !== undefined && baseDir.trim().length > 0) {
|
|
94
|
+
exitOnSensitiveRoot([baseDir], checkSensitivePath, 'BASE_DIR');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export async function resolveCliBaseDirsOrExit(cliRoots) {
|
|
98
|
+
// Screen the raw env-supplied paths before the resolver realpath-
|
|
99
|
+
// normalizes them, so a literal `BASE_DIR=/etc` is rejected with the
|
|
100
|
+
// env var as the attribution surface.
|
|
101
|
+
if (cliRoots.length === 0) {
|
|
102
|
+
exitOnSensitiveEnvRoots();
|
|
103
|
+
}
|
|
104
|
+
const result = await resolveBaseDirs({
|
|
105
|
+
cliRoots,
|
|
106
|
+
envBaseDirs: process.env['BASE_DIRS'],
|
|
107
|
+
envBaseDir: process.env['BASE_DIR'],
|
|
108
|
+
cwd: process.cwd(),
|
|
109
|
+
});
|
|
110
|
+
if (!result.ok) {
|
|
111
|
+
console.error(result.error.message);
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
// The policy applies to every effective root, whatever its source: a CLI
|
|
115
|
+
// root may be a symlink whose realpath-resolved target the subcommand's
|
|
116
|
+
// pre-validation missed. Reported under `--base-dir`, the flag the user
|
|
117
|
+
// most directly controls.
|
|
118
|
+
exitOnSensitiveRoot(result.config.baseDirs, validatePath, '--base-dir');
|
|
119
|
+
return { config: result.config, warnings: result.warnings };
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/cli/common.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/cli/delete.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAoIjD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,aAAa,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+DhG"}
|