agentfootprint 8.9.0 → 8.10.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/AGENTS.md +2 -0
- package/CLAUDE.md +4 -0
- package/bin/agentfootprint-index.mjs +192 -0
- package/dist/doors/rag.js +66 -0
- package/dist/doors/rag.js.map +1 -0
- package/dist/esm/doors/rag.d.ts +49 -0
- package/dist/esm/doors/rag.js +50 -0
- package/dist/esm/doors/rag.js.map +1 -0
- package/dist/esm/rag/hash.d.ts +2 -0
- package/dist/esm/rag/hash.js +22 -0
- package/dist/esm/rag/hash.js.map +1 -0
- package/dist/esm/rag/index.d.ts +17 -0
- package/dist/esm/rag/index.js +17 -0
- package/dist/esm/rag/index.js.map +1 -0
- package/dist/esm/rag/indexCorpus.d.ts +102 -0
- package/dist/esm/rag/indexCorpus.js +339 -0
- package/dist/esm/rag/indexCorpus.js.map +1 -0
- package/dist/esm/rag/indexFolder.d.ts +40 -0
- package/dist/esm/rag/indexFolder.js +42 -0
- package/dist/esm/rag/indexFolder.js.map +1 -0
- package/dist/esm/rag/loadDocuments.d.ts +34 -0
- package/dist/esm/rag/loadDocuments.js +160 -0
- package/dist/esm/rag/loadDocuments.js.map +1 -0
- package/dist/esm/rag/loaders/html.d.ts +42 -0
- package/dist/esm/rag/loaders/html.js +48 -0
- package/dist/esm/rag/loaders/html.js.map +1 -0
- package/dist/esm/rag/loaders/index.d.ts +30 -0
- package/dist/esm/rag/loaders/index.js +24 -0
- package/dist/esm/rag/loaders/index.js.map +1 -0
- package/dist/esm/rag/loaders/markdown.d.ts +27 -0
- package/dist/esm/rag/loaders/markdown.js +12 -0
- package/dist/esm/rag/loaders/markdown.js.map +1 -0
- package/dist/esm/rag/loaders/mock.d.ts +28 -0
- package/dist/esm/rag/loaders/mock.js +14 -0
- package/dist/esm/rag/loaders/mock.js.map +1 -0
- package/dist/esm/rag/loaders/pdf.d.ts +39 -0
- package/dist/esm/rag/loaders/pdf.js +90 -0
- package/dist/esm/rag/loaders/pdf.js.map +1 -0
- package/dist/esm/rag/loaders/text.d.ts +23 -0
- package/dist/esm/rag/loaders/text.js +21 -0
- package/dist/esm/rag/loaders/text.js.map +1 -0
- package/dist/esm/rag/splitDocuments.d.ts +21 -0
- package/dist/esm/rag/splitDocuments.js +65 -0
- package/dist/esm/rag/splitDocuments.js.map +1 -0
- package/dist/esm/rag/splitters/byHeading.d.ts +36 -0
- package/dist/esm/rag/splitters/byHeading.js +66 -0
- package/dist/esm/rag/splitters/byHeading.js.map +1 -0
- package/dist/esm/rag/splitters/byParagraph.d.ts +24 -0
- package/dist/esm/rag/splitters/byParagraph.js +16 -0
- package/dist/esm/rag/splitters/byParagraph.js.map +1 -0
- package/dist/esm/rag/splitters/constants.d.ts +19 -0
- package/dist/esm/rag/splitters/constants.js +20 -0
- package/dist/esm/rag/splitters/constants.js.map +1 -0
- package/dist/esm/rag/splitters/fixedWithOverlap.d.ts +31 -0
- package/dist/esm/rag/splitters/fixedWithOverlap.js +34 -0
- package/dist/esm/rag/splitters/fixedWithOverlap.js.map +1 -0
- package/dist/esm/rag/splitters/index.d.ts +50 -0
- package/dist/esm/rag/splitters/index.js +51 -0
- package/dist/esm/rag/splitters/index.js.map +1 -0
- package/dist/esm/rag/splitters/shared.d.ts +87 -0
- package/dist/esm/rag/splitters/shared.js +188 -0
- package/dist/esm/rag/splitters/shared.js.map +1 -0
- package/dist/esm/rag/splitters/wholeDocument.d.ts +16 -0
- package/dist/esm/rag/splitters/wholeDocument.js +10 -0
- package/dist/esm/rag/splitters/wholeDocument.js.map +1 -0
- package/dist/esm/rag/types.d.ts +200 -0
- package/dist/esm/rag/types.js +20 -0
- package/dist/esm/rag/types.js.map +1 -0
- package/dist/rag/hash.js +26 -0
- package/dist/rag/hash.js.map +1 -0
- package/dist/rag/index.js +40 -0
- package/dist/rag/index.js.map +1 -0
- package/dist/rag/indexCorpus.js +344 -0
- package/dist/rag/indexCorpus.js.map +1 -0
- package/dist/rag/indexFolder.js +46 -0
- package/dist/rag/indexFolder.js.map +1 -0
- package/dist/rag/loadDocuments.js +164 -0
- package/dist/rag/loadDocuments.js.map +1 -0
- package/dist/rag/loaders/html.js +53 -0
- package/dist/rag/loaders/html.js.map +1 -0
- package/dist/rag/loaders/index.js +33 -0
- package/dist/rag/loaders/index.js.map +1 -0
- package/dist/rag/loaders/markdown.js +16 -0
- package/dist/rag/loaders/markdown.js.map +1 -0
- package/dist/rag/loaders/mock.js +18 -0
- package/dist/rag/loaders/mock.js.map +1 -0
- package/dist/rag/loaders/pdf.js +118 -0
- package/dist/rag/loaders/pdf.js.map +1 -0
- package/dist/rag/loaders/text.js +26 -0
- package/dist/rag/loaders/text.js.map +1 -0
- package/dist/rag/splitDocuments.js +69 -0
- package/dist/rag/splitDocuments.js.map +1 -0
- package/dist/rag/splitters/byHeading.js +70 -0
- package/dist/rag/splitters/byHeading.js.map +1 -0
- package/dist/rag/splitters/byParagraph.js +20 -0
- package/dist/rag/splitters/byParagraph.js.map +1 -0
- package/dist/rag/splitters/constants.js +23 -0
- package/dist/rag/splitters/constants.js.map +1 -0
- package/dist/rag/splitters/fixedWithOverlap.js +38 -0
- package/dist/rag/splitters/fixedWithOverlap.js.map +1 -0
- package/dist/rag/splitters/index.js +60 -0
- package/dist/rag/splitters/index.js.map +1 -0
- package/dist/rag/splitters/shared.js +199 -0
- package/dist/rag/splitters/shared.js.map +1 -0
- package/dist/rag/splitters/wholeDocument.js +14 -0
- package/dist/rag/splitters/wholeDocument.js.map +1 -0
- package/dist/rag/types.js +21 -0
- package/dist/rag/types.js.map +1 -0
- package/dist/types/doors/rag.d.ts +50 -0
- package/dist/types/doors/rag.d.ts.map +1 -0
- package/dist/types/rag/hash.d.ts +3 -0
- package/dist/types/rag/hash.d.ts.map +1 -0
- package/dist/types/rag/index.d.ts +18 -0
- package/dist/types/rag/index.d.ts.map +1 -0
- package/dist/types/rag/indexCorpus.d.ts +103 -0
- package/dist/types/rag/indexCorpus.d.ts.map +1 -0
- package/dist/types/rag/indexFolder.d.ts +41 -0
- package/dist/types/rag/indexFolder.d.ts.map +1 -0
- package/dist/types/rag/loadDocuments.d.ts +35 -0
- package/dist/types/rag/loadDocuments.d.ts.map +1 -0
- package/dist/types/rag/loaders/html.d.ts +43 -0
- package/dist/types/rag/loaders/html.d.ts.map +1 -0
- package/dist/types/rag/loaders/index.d.ts +31 -0
- package/dist/types/rag/loaders/index.d.ts.map +1 -0
- package/dist/types/rag/loaders/markdown.d.ts +28 -0
- package/dist/types/rag/loaders/markdown.d.ts.map +1 -0
- package/dist/types/rag/loaders/mock.d.ts +29 -0
- package/dist/types/rag/loaders/mock.d.ts.map +1 -0
- package/dist/types/rag/loaders/pdf.d.ts +40 -0
- package/dist/types/rag/loaders/pdf.d.ts.map +1 -0
- package/dist/types/rag/loaders/text.d.ts +24 -0
- package/dist/types/rag/loaders/text.d.ts.map +1 -0
- package/dist/types/rag/splitDocuments.d.ts +22 -0
- package/dist/types/rag/splitDocuments.d.ts.map +1 -0
- package/dist/types/rag/splitters/byHeading.d.ts +37 -0
- package/dist/types/rag/splitters/byHeading.d.ts.map +1 -0
- package/dist/types/rag/splitters/byParagraph.d.ts +25 -0
- package/dist/types/rag/splitters/byParagraph.d.ts.map +1 -0
- package/dist/types/rag/splitters/constants.d.ts +20 -0
- package/dist/types/rag/splitters/constants.d.ts.map +1 -0
- package/dist/types/rag/splitters/fixedWithOverlap.d.ts +32 -0
- package/dist/types/rag/splitters/fixedWithOverlap.d.ts.map +1 -0
- package/dist/types/rag/splitters/index.d.ts +51 -0
- package/dist/types/rag/splitters/index.d.ts.map +1 -0
- package/dist/types/rag/splitters/shared.d.ts +88 -0
- package/dist/types/rag/splitters/shared.d.ts.map +1 -0
- package/dist/types/rag/splitters/wholeDocument.d.ts +17 -0
- package/dist/types/rag/splitters/wholeDocument.d.ts.map +1 -0
- package/dist/types/rag/types.d.ts +201 -0
- package/dist/types/rag/types.d.ts.map +1 -0
- package/package.json +23 -4
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.byHeading = void 0;
|
|
4
|
+
const constants_js_1 = require("./constants.js");
|
|
5
|
+
const shared_js_1 = require("./shared.js");
|
|
6
|
+
/** ATX headings only (`# Title`). Setext (`Title\n=====`) is rare in docs corpora. */
|
|
7
|
+
const HEADING = /^(#{1,6})[ \t]+(.+?)[ \t]*$/gm;
|
|
8
|
+
function byHeading(options = {}) {
|
|
9
|
+
const maxChars = options.maxChars ?? constants_js_1.DEFAULT_MAX_CHARS;
|
|
10
|
+
const overlapChars = options.overlapChars ?? constants_js_1.DEFAULT_OVERLAP_CHARS;
|
|
11
|
+
const maxLevel = options.maxLevel ?? 6;
|
|
12
|
+
return {
|
|
13
|
+
name: 'byHeading',
|
|
14
|
+
split(doc) {
|
|
15
|
+
const text = doc.text;
|
|
16
|
+
// Where each section starts, and what it is called.
|
|
17
|
+
const starts = [];
|
|
18
|
+
HEADING.lastIndex = 0;
|
|
19
|
+
let match;
|
|
20
|
+
while ((match = HEADING.exec(text)) !== null) {
|
|
21
|
+
if ((match[1] ?? '').length > maxLevel)
|
|
22
|
+
continue;
|
|
23
|
+
starts.push({ offset: match.index, heading: match[2] });
|
|
24
|
+
}
|
|
25
|
+
// A document with no headings at all is a paragraph document; say so by
|
|
26
|
+
// doing the paragraph thing rather than returning one giant chunk.
|
|
27
|
+
if (starts.length === 0) {
|
|
28
|
+
const packed = (0, shared_js_1.packSpans)((0, shared_js_1.paragraphSpans)(text), maxChars);
|
|
29
|
+
const cut = packed.flatMap((s) => s.end - s.start > maxChars ? (0, shared_js_1.hardCut)(s, maxChars, overlapChars) : [s]);
|
|
30
|
+
return (0, shared_js_1.toPieces)(doc, (0, shared_js_1.applyOverlap)((0, shared_js_1.foldRunts)(cut), overlapChars));
|
|
31
|
+
}
|
|
32
|
+
const sections = [];
|
|
33
|
+
// Preamble before the first heading — its own section, unnamed.
|
|
34
|
+
const firstStart = starts[0]?.offset ?? 0;
|
|
35
|
+
if (firstStart > 0)
|
|
36
|
+
sections.push({ start: 0, end: firstStart });
|
|
37
|
+
for (let i = 0; i < starts.length; i++) {
|
|
38
|
+
const start = starts[i]?.offset ?? 0;
|
|
39
|
+
const end = starts[i + 1]?.offset ?? text.length;
|
|
40
|
+
const heading = starts[i]?.heading;
|
|
41
|
+
sections.push({ start, end, ...(heading !== undefined && { heading }) });
|
|
42
|
+
}
|
|
43
|
+
// Sections that fit stay whole; the rest are packed by paragraph WITHIN
|
|
44
|
+
// the section, so a boundary never merges two headings' content.
|
|
45
|
+
const spans = [];
|
|
46
|
+
for (const section of sections) {
|
|
47
|
+
if (section.end - section.start <= maxChars) {
|
|
48
|
+
spans.push(section);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const inner = (0, shared_js_1.paragraphSpans)(text.slice(section.start, section.end)).map((s) => ({
|
|
52
|
+
start: section.start + s.start,
|
|
53
|
+
end: section.start + s.end,
|
|
54
|
+
...(section.heading !== undefined && { heading: section.heading }),
|
|
55
|
+
}));
|
|
56
|
+
for (const packedSpan of (0, shared_js_1.packSpans)(inner, maxChars)) {
|
|
57
|
+
if (packedSpan.end - packedSpan.start > maxChars) {
|
|
58
|
+
spans.push(...(0, shared_js_1.hardCut)(packedSpan, maxChars, overlapChars));
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
spans.push(packedSpan);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return (0, shared_js_1.toPieces)(doc, (0, shared_js_1.applyOverlap)((0, shared_js_1.foldRunts)(spans), overlapChars));
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
exports.byHeading = byHeading;
|
|
70
|
+
//# sourceMappingURL=byHeading.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"byHeading.js","sourceRoot":"","sources":["../../../src/rag/splitters/byHeading.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.byParagraph = void 0;
|
|
4
|
+
const constants_js_1 = require("./constants.js");
|
|
5
|
+
const shared_js_1 = require("./shared.js");
|
|
6
|
+
function byParagraph(options = {}) {
|
|
7
|
+
const maxChars = options.maxChars ?? constants_js_1.DEFAULT_MAX_CHARS;
|
|
8
|
+
const overlapChars = options.overlapChars ?? constants_js_1.DEFAULT_OVERLAP_CHARS;
|
|
9
|
+
return {
|
|
10
|
+
name: 'byParagraph',
|
|
11
|
+
split(doc) {
|
|
12
|
+
const paragraphs = (0, shared_js_1.paragraphSpans)(doc.text);
|
|
13
|
+
const packed = (0, shared_js_1.packSpans)(paragraphs, maxChars);
|
|
14
|
+
const cut = packed.flatMap((span) => span.end - span.start > maxChars ? (0, shared_js_1.hardCut)(span, maxChars, overlapChars) : [span]);
|
|
15
|
+
return (0, shared_js_1.toPieces)(doc, (0, shared_js_1.applyOverlap)((0, shared_js_1.foldRunts)(cut), overlapChars));
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
exports.byParagraph = byParagraph;
|
|
20
|
+
//# sourceMappingURL=byParagraph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"byParagraph.js","sourceRoot":"","sources":["../../../src/rag/splitters/byParagraph.ts"],"names":[],"mappings":";;;AAiBA,iDAA0E;AAC1E,2CAAoG;AASpG,SAAgB,WAAW,CAAC,UAA8B,EAAE;IAC1D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,gCAAiB,CAAC;IACvD,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,oCAAqB,CAAC;IAEnE,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,KAAK,CAAC,GAAmB;YACvB,MAAM,UAAU,GAAG,IAAA,0BAAc,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC/C,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAClC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAA,mBAAO,EAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAClF,CAAC;YACF,OAAO,IAAA,oBAAQ,EAAC,GAAG,EAAE,IAAA,wBAAY,EAAC,IAAA,qBAAS,EAAC,GAAG,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;QACnE,CAAC;KACF,CAAC;AACJ,CAAC;AAfD,kCAeC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The two numbers every splitter defaults to, in one place so they cannot
|
|
4
|
+
* drift apart between strategies.
|
|
5
|
+
*
|
|
6
|
+
* See `splitters/index.ts` for the measurement they come from: `localEmbedder`
|
|
7
|
+
* truncates at 512 wordpiece tokens (~1,800–2,000 characters), silently, and
|
|
8
|
+
* 1,000 characters is ~250 tokens — comfortably inside it.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.MIN_CHUNK_CHARS = exports.DEFAULT_OVERLAP_CHARS = exports.DEFAULT_MAX_CHARS = void 0;
|
|
12
|
+
/** Target chunk size in characters. ~250 wordpiece tokens of English. */
|
|
13
|
+
exports.DEFAULT_MAX_CHARS = 1000;
|
|
14
|
+
/** Overlap between adjacent chunks, so a boundary-spanning sentence is whole somewhere. */
|
|
15
|
+
exports.DEFAULT_OVERLAP_CHARS = 150;
|
|
16
|
+
/**
|
|
17
|
+
* Below this, a trailing fragment is folded back into the previous chunk
|
|
18
|
+
* rather than shipped on its own. A 12-character chunk consisting of one
|
|
19
|
+
* heading and no body embeds to noise and takes a top-K slot from a real
|
|
20
|
+
* passage.
|
|
21
|
+
*/
|
|
22
|
+
exports.MIN_CHUNK_CHARS = 50;
|
|
23
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/rag/splitters/constants.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,yEAAyE;AAC5D,QAAA,iBAAiB,GAAG,IAAI,CAAC;AAEtC,2FAA2F;AAC9E,QAAA,qBAAqB,GAAG,GAAG,CAAC;AAEzC;;;;;GAKG;AACU,QAAA,eAAe,GAAG,EAAE,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fixedWithOverlap = void 0;
|
|
4
|
+
const constants_js_1 = require("./constants.js");
|
|
5
|
+
const shared_js_1 = require("./shared.js");
|
|
6
|
+
function fixedWithOverlap(options = {}) {
|
|
7
|
+
const chars = options.chars ?? constants_js_1.DEFAULT_MAX_CHARS;
|
|
8
|
+
const overlapChars = options.overlapChars ?? constants_js_1.DEFAULT_OVERLAP_CHARS;
|
|
9
|
+
const wordWindow = options.wordWindow ?? 40;
|
|
10
|
+
return {
|
|
11
|
+
name: 'fixedWithOverlap',
|
|
12
|
+
split(doc) {
|
|
13
|
+
const text = doc.text;
|
|
14
|
+
const spans = [];
|
|
15
|
+
let start = 0;
|
|
16
|
+
while (start < text.length) {
|
|
17
|
+
let end = Math.min(text.length, start + chars);
|
|
18
|
+
// Nudge back to whitespace, but never past the window and never so far
|
|
19
|
+
// that the chunk collapses.
|
|
20
|
+
if (end < text.length && wordWindow > 0) {
|
|
21
|
+
const floor = Math.max(start + 1, end - wordWindow);
|
|
22
|
+
let candidate = end;
|
|
23
|
+
while (candidate > floor && !/\s/.test(text[candidate] ?? ''))
|
|
24
|
+
candidate -= 1;
|
|
25
|
+
if (candidate > floor)
|
|
26
|
+
end = candidate;
|
|
27
|
+
}
|
|
28
|
+
spans.push({ start, end });
|
|
29
|
+
if (end >= text.length)
|
|
30
|
+
break;
|
|
31
|
+
start = end;
|
|
32
|
+
}
|
|
33
|
+
return (0, shared_js_1.toPieces)(doc, (0, shared_js_1.applyOverlap)((0, shared_js_1.foldRunts)(spans), overlapChars));
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
exports.fixedWithOverlap = fixedWithOverlap;
|
|
38
|
+
//# sourceMappingURL=fixedWithOverlap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixedWithOverlap.js","sourceRoot":"","sources":["../../../src/rag/splitters/fixedWithOverlap.ts"],"names":[],"mappings":";;;AAmBA,iDAA0E;AAC1E,2CAA2E;AAc3E,SAAgB,gBAAgB,CAAC,UAAmC,EAAE;IACpE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,gCAAiB,CAAC;IACjD,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,oCAAqB,CAAC;IACnE,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;IAE5C,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,KAAK,CAAC,GAAmB;YACvB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;YACtB,MAAM,KAAK,GAAW,EAAE,CAAC;YACzB,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,OAAO,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC3B,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,KAAK,CAAC,CAAC;gBAC/C,uEAAuE;gBACvE,4BAA4B;gBAC5B,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;oBACxC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,GAAG,UAAU,CAAC,CAAC;oBACpD,IAAI,SAAS,GAAG,GAAG,CAAC;oBACpB,OAAO,SAAS,GAAG,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;wBAAE,SAAS,IAAI,CAAC,CAAC;oBAC9E,IAAI,SAAS,GAAG,KAAK;wBAAE,GAAG,GAAG,SAAS,CAAC;gBACzC,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC3B,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM;oBAAE,MAAM;gBAC9B,KAAK,GAAG,GAAG,CAAC;YACd,CAAC;YACD,OAAO,IAAA,oBAAQ,EAAC,GAAG,EAAE,IAAA,wBAAY,EAAC,IAAA,qBAAS,EAAC,KAAK,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;QACrE,CAAC;KACF,CAAC;AACJ,CAAC;AA5BD,4CA4BC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_OVERLAP_CHARS = exports.DEFAULT_MAX_CHARS = exports.wholeDocument = exports.fixedWithOverlap = exports.byHeading = exports.byParagraph = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* rag/splitters — where a document gets cut, and why there.
|
|
6
|
+
*
|
|
7
|
+
* Pattern: Strategy family (factory functions), the same shape as the window
|
|
8
|
+
* and retrieval families. Not a `{ kind }` union: a splitter you write
|
|
9
|
+
* yourself is the same shape as these, unused ones stay out of a
|
|
10
|
+
* bundle, and adding one needs no switch edited anywhere.
|
|
11
|
+
* Role: rag/ layer.
|
|
12
|
+
* Emits: N/A.
|
|
13
|
+
*
|
|
14
|
+
* ── The defaults, and the measurement behind them ───────────────────────────
|
|
15
|
+
*
|
|
16
|
+
* `maxChars: 1000`, `overlapChars: 150`. Those numbers are chosen by
|
|
17
|
+
* CONSTRAINT, not by fashion, and the constraint is measurable:
|
|
18
|
+
*
|
|
19
|
+
* **`localEmbedder`'s default model silently truncates at 512 wordpiece
|
|
20
|
+
* tokens.** Measured directly — embed a long text, embed the same text with an
|
|
21
|
+
* unrelated tail appended, and compare. At 508 base tokens the tail still
|
|
22
|
+
* moves the vector (cosine 0.9965). At 596 it does not (cosine 0.999999): the
|
|
23
|
+
* tail was discarded and nothing said so. 512 wordpiece tokens is roughly
|
|
24
|
+
* 1,800–2,000 characters of English.
|
|
25
|
+
*
|
|
26
|
+
* A chunk of 1,000 characters is about 250 tokens. That sits comfortably
|
|
27
|
+
* inside that cliff, inside the 256-token length the sentence-transformer
|
|
28
|
+
* family was actually trained at, and trivially inside `openaiEmbedder`'s
|
|
29
|
+
* 8,191. Raise it and you approach a limit whose failure mode is silence —
|
|
30
|
+
* half your chunk embedded, full score reported.
|
|
31
|
+
*
|
|
32
|
+
* The 150-character overlap (15%) exists so a sentence spanning a boundary is
|
|
33
|
+
* whole in one of the two neighbours. It is the smallest overlap that reliably
|
|
34
|
+
* does that for English prose; there is nothing deeper claimed for it.
|
|
35
|
+
*
|
|
36
|
+
* ── Which one to use ────────────────────────────────────────────────────────
|
|
37
|
+
*
|
|
38
|
+
* | splitter | cuts on | use when |
|
|
39
|
+
* |---|---|---|
|
|
40
|
+
* | `byHeading()` | Markdown `#` lines | the document declares its own sections — **not a heuristic** |
|
|
41
|
+
* | `byParagraph()` | blank lines | prose with no headings |
|
|
42
|
+
* | `fixedWithOverlap()` | character count | text with no structure at all (transcripts, OCR) |
|
|
43
|
+
* | `wholeDocument()` | nothing | short documents that are already one idea |
|
|
44
|
+
*
|
|
45
|
+
* `byHeading` is the only one that is not guessing. The author already marked
|
|
46
|
+
* where the sections are; the others are inferring boundaries from typography.
|
|
47
|
+
* That is why it is the default for Markdown.
|
|
48
|
+
*/
|
|
49
|
+
var byParagraph_js_1 = require("./byParagraph.js");
|
|
50
|
+
Object.defineProperty(exports, "byParagraph", { enumerable: true, get: function () { return byParagraph_js_1.byParagraph; } });
|
|
51
|
+
var byHeading_js_1 = require("./byHeading.js");
|
|
52
|
+
Object.defineProperty(exports, "byHeading", { enumerable: true, get: function () { return byHeading_js_1.byHeading; } });
|
|
53
|
+
var fixedWithOverlap_js_1 = require("./fixedWithOverlap.js");
|
|
54
|
+
Object.defineProperty(exports, "fixedWithOverlap", { enumerable: true, get: function () { return fixedWithOverlap_js_1.fixedWithOverlap; } });
|
|
55
|
+
var wholeDocument_js_1 = require("./wholeDocument.js");
|
|
56
|
+
Object.defineProperty(exports, "wholeDocument", { enumerable: true, get: function () { return wholeDocument_js_1.wholeDocument; } });
|
|
57
|
+
var constants_js_1 = require("./constants.js");
|
|
58
|
+
Object.defineProperty(exports, "DEFAULT_MAX_CHARS", { enumerable: true, get: function () { return constants_js_1.DEFAULT_MAX_CHARS; } });
|
|
59
|
+
Object.defineProperty(exports, "DEFAULT_OVERLAP_CHARS", { enumerable: true, get: function () { return constants_js_1.DEFAULT_OVERLAP_CHARS; } });
|
|
60
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/rag/splitters/index.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,mDAAwE;AAA/D,6GAAA,WAAW,OAAA;AACpB,+CAAkE;AAAzD,yGAAA,SAAS,OAAA;AAClB,6DAAuF;AAA9E,uHAAA,gBAAgB,OAAA;AACzB,uDAAmD;AAA1C,iHAAA,aAAa,OAAA;AACtB,+CAA0E;AAAjE,iHAAA,iBAAiB,OAAA;AAAE,qHAAA,qBAAqB,OAAA"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.paragraphSpans = exports.hardCut = exports.toPieces = exports.foldRunts = exports.applyOverlap = exports.packSpans = exports.trimSpan = exports.pageLocator = void 0;
|
|
4
|
+
const constants_js_1 = require("./constants.js");
|
|
5
|
+
/**
|
|
6
|
+
* Which page an offset falls on, 1-based, or `undefined` when the document is
|
|
7
|
+
* not paginated.
|
|
8
|
+
*
|
|
9
|
+
* Pages were joined with `'\n\n'` by the loader, so the boundaries are
|
|
10
|
+
* reconstructible exactly. A chunk that straddles a page break is attributed
|
|
11
|
+
* to the page it STARTS on — one number, the one you would turn to first.
|
|
12
|
+
*/
|
|
13
|
+
function pageLocator(doc) {
|
|
14
|
+
const pages = doc.pages;
|
|
15
|
+
if (!pages || pages.length === 0)
|
|
16
|
+
return () => undefined;
|
|
17
|
+
const bounds = [];
|
|
18
|
+
let cursor = 0;
|
|
19
|
+
for (const page of pages) {
|
|
20
|
+
bounds.push(cursor);
|
|
21
|
+
cursor += page.length + 2; // the '\n\n' the loader joined with
|
|
22
|
+
}
|
|
23
|
+
return (offset) => {
|
|
24
|
+
let page = 1;
|
|
25
|
+
for (let i = 0; i < bounds.length; i++) {
|
|
26
|
+
if (offset >= (bounds[i] ?? 0))
|
|
27
|
+
page = i + 1;
|
|
28
|
+
else
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
return page;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
exports.pageLocator = pageLocator;
|
|
35
|
+
/**
|
|
36
|
+
* Trim a span inward past leading/trailing whitespace, keeping the offsets
|
|
37
|
+
* honest.
|
|
38
|
+
*
|
|
39
|
+
* The naive version — `slice().trim()` — produces text that no longer matches
|
|
40
|
+
* its own offsets. This moves the offsets instead, so the invariant holds.
|
|
41
|
+
* Returns `undefined` when the span is entirely whitespace.
|
|
42
|
+
*/
|
|
43
|
+
function trimSpan(text, span) {
|
|
44
|
+
let start = span.start;
|
|
45
|
+
let end = span.end;
|
|
46
|
+
while (start < end && /\s/.test(text[start] ?? ''))
|
|
47
|
+
start += 1;
|
|
48
|
+
while (end > start && /\s/.test(text[end - 1] ?? ''))
|
|
49
|
+
end -= 1;
|
|
50
|
+
if (start >= end)
|
|
51
|
+
return undefined;
|
|
52
|
+
return {
|
|
53
|
+
start,
|
|
54
|
+
end,
|
|
55
|
+
...(span.heading !== undefined && { heading: span.heading }),
|
|
56
|
+
...(span.contentStart !== undefined && { contentStart: span.contentStart }),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
exports.trimSpan = trimSpan;
|
|
60
|
+
/**
|
|
61
|
+
* Pack consecutive units (paragraphs, lines) into spans of at most `maxChars`,
|
|
62
|
+
* then apply `overlapChars` of backward overlap.
|
|
63
|
+
*
|
|
64
|
+
* Units are never split by this function — a single unit longer than `maxChars`
|
|
65
|
+
* becomes its own oversized span, and the caller decides whether to hard-cut
|
|
66
|
+
* it. That separation matters: a 4,000-character paragraph is a real thing in
|
|
67
|
+
* real documents, and silently slicing it mid-word is a different decision from
|
|
68
|
+
* packing.
|
|
69
|
+
*/
|
|
70
|
+
function packSpans(units, maxChars) {
|
|
71
|
+
const out = [];
|
|
72
|
+
let current;
|
|
73
|
+
for (const unit of units) {
|
|
74
|
+
if (current === undefined) {
|
|
75
|
+
current = unit;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
// Same heading, and the merged span still fits.
|
|
79
|
+
const fits = unit.end - current.start <= maxChars;
|
|
80
|
+
const sameSection = current.heading === unit.heading;
|
|
81
|
+
if (fits && sameSection) {
|
|
82
|
+
current = {
|
|
83
|
+
start: current.start,
|
|
84
|
+
end: unit.end,
|
|
85
|
+
...(current.heading !== undefined && { heading: current.heading }),
|
|
86
|
+
};
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
out.push(current);
|
|
90
|
+
current = unit;
|
|
91
|
+
}
|
|
92
|
+
if (current !== undefined)
|
|
93
|
+
out.push(current);
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
exports.packSpans = packSpans;
|
|
97
|
+
/**
|
|
98
|
+
* Extend each span backward by `overlapChars`, without crossing the previous
|
|
99
|
+
* span's start.
|
|
100
|
+
*
|
|
101
|
+
* Backward rather than forward so a chunk always ENDS on the boundary its
|
|
102
|
+
* strategy chose — a heading section that ends mid-sentence because of overlap
|
|
103
|
+
* would be a section that lies about where it ends.
|
|
104
|
+
*/
|
|
105
|
+
function applyOverlap(spans, overlapChars) {
|
|
106
|
+
if (overlapChars <= 0)
|
|
107
|
+
return [...spans];
|
|
108
|
+
return spans.map((span, i) => {
|
|
109
|
+
if (i === 0)
|
|
110
|
+
return span;
|
|
111
|
+
const floor = spans[i - 1]?.start ?? 0;
|
|
112
|
+
const start = Math.max(floor, span.start - overlapChars);
|
|
113
|
+
// Remember where the chunk's own content starts, so the page it is
|
|
114
|
+
// attributed to is the page it is ABOUT, not the page its run-up borrowed
|
|
115
|
+
// from.
|
|
116
|
+
return start === span.start ? span : { ...span, start, contentStart: span.start };
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
exports.applyOverlap = applyOverlap;
|
|
120
|
+
/**
|
|
121
|
+
* Fold a too-small span back into its predecessor.
|
|
122
|
+
*
|
|
123
|
+
* A fragment of a few characters — a stray heading, a signature line — embeds
|
|
124
|
+
* to noise and then competes for a top-K slot with real passages.
|
|
125
|
+
*
|
|
126
|
+
* **It never folds across a heading boundary.** A merged chunk carries the
|
|
127
|
+
* FIRST span's heading, so folding a short section into the one before it
|
|
128
|
+
* would produce a chunk labelled `heading="Alpha"` whose text is Beta's — a
|
|
129
|
+
* citation that names the wrong section, which is worse than a small chunk.
|
|
130
|
+
* Two spans merge only when they are already the same section.
|
|
131
|
+
*/
|
|
132
|
+
function foldRunts(spans, minChars = constants_js_1.MIN_CHUNK_CHARS) {
|
|
133
|
+
const out = [];
|
|
134
|
+
for (const span of spans) {
|
|
135
|
+
const previous = out[out.length - 1];
|
|
136
|
+
const sameSection = previous !== undefined && previous.heading === span.heading;
|
|
137
|
+
if (previous !== undefined && sameSection && span.end - span.start < minChars) {
|
|
138
|
+
out[out.length - 1] = {
|
|
139
|
+
start: previous.start,
|
|
140
|
+
end: span.end,
|
|
141
|
+
...(previous.heading !== undefined && { heading: previous.heading }),
|
|
142
|
+
};
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
out.push(span);
|
|
146
|
+
}
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
149
|
+
exports.foldRunts = foldRunts;
|
|
150
|
+
/** Turn spans into pieces, slicing the text so the invariant holds by construction. */
|
|
151
|
+
function toPieces(doc, spans) {
|
|
152
|
+
const pageAt = pageLocator(doc);
|
|
153
|
+
const pieces = [];
|
|
154
|
+
for (const span of spans) {
|
|
155
|
+
const trimmed = trimSpan(doc.text, span);
|
|
156
|
+
if (trimmed === undefined)
|
|
157
|
+
continue;
|
|
158
|
+
// See `Span.contentStart`: the page is the one this chunk is about.
|
|
159
|
+
const page = pageAt(span.contentStart ?? trimmed.start);
|
|
160
|
+
pieces.push({
|
|
161
|
+
// Sliced, never concatenated. This is the invariant.
|
|
162
|
+
text: doc.text.slice(trimmed.start, trimmed.end),
|
|
163
|
+
charStart: trimmed.start,
|
|
164
|
+
charEnd: trimmed.end,
|
|
165
|
+
...(trimmed.heading !== undefined && { heading: trimmed.heading }),
|
|
166
|
+
...(page !== undefined && { page }),
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
return pieces;
|
|
170
|
+
}
|
|
171
|
+
exports.toPieces = toPieces;
|
|
172
|
+
/** Hard-cut a span that no packing could fit, at `maxChars` with overlap. */
|
|
173
|
+
function hardCut(span, maxChars, overlapChars) {
|
|
174
|
+
const out = [];
|
|
175
|
+
const stride = Math.max(1, maxChars - overlapChars);
|
|
176
|
+
for (let start = span.start; start < span.end; start += stride) {
|
|
177
|
+
const end = Math.min(span.end, start + maxChars);
|
|
178
|
+
out.push({ start, end, ...(span.heading !== undefined && { heading: span.heading }) });
|
|
179
|
+
if (end >= span.end)
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
return out;
|
|
183
|
+
}
|
|
184
|
+
exports.hardCut = hardCut;
|
|
185
|
+
/** Split into paragraph spans on blank lines, keeping offsets. */
|
|
186
|
+
function paragraphSpans(text) {
|
|
187
|
+
const spans = [];
|
|
188
|
+
const separator = /\n[ \t]*\n/g;
|
|
189
|
+
let cursor = 0;
|
|
190
|
+
let match;
|
|
191
|
+
while ((match = separator.exec(text)) !== null) {
|
|
192
|
+
spans.push({ start: cursor, end: match.index });
|
|
193
|
+
cursor = match.index + match[0].length;
|
|
194
|
+
}
|
|
195
|
+
spans.push({ start: cursor, end: text.length });
|
|
196
|
+
return spans.filter((s) => s.end > s.start);
|
|
197
|
+
}
|
|
198
|
+
exports.paragraphSpans = paragraphSpans;
|
|
199
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/rag/splitters/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wholeDocument = void 0;
|
|
4
|
+
const shared_js_1 = require("./shared.js");
|
|
5
|
+
function wholeDocument() {
|
|
6
|
+
return {
|
|
7
|
+
name: 'wholeDocument',
|
|
8
|
+
split(doc) {
|
|
9
|
+
return (0, shared_js_1.toPieces)(doc, [{ start: 0, end: doc.text.length }]);
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
exports.wholeDocument = wholeDocument;
|
|
14
|
+
//# sourceMappingURL=wholeDocument.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wholeDocument.js","sourceRoot":"","sources":["../../../src/rag/splitters/wholeDocument.ts"],"names":[],"mappings":";;;AAeA,2CAAuC;AAEvC,SAAgB,aAAa;IAC3B,OAAO;QACL,IAAI,EAAE,eAAe;QACrB,KAAK,CAAC,GAAmB;YACvB,OAAO,IAAA,oBAAQ,EAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC7D,CAAC;KACF,CAAC;AACJ,CAAC;AAPD,sCAOC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* rag/types — the ports and value objects between a folder of documents and
|
|
4
|
+
* an answering agent.
|
|
5
|
+
*
|
|
6
|
+
* Pattern: Ports (DocumentLoader, Splitter) + value objects (LoadedDocument,
|
|
7
|
+
* Chunk, IndexReport).
|
|
8
|
+
* Role: rag/ layer. The law this folder exists to keep is stated once,
|
|
9
|
+
* here, because everything downstream implements a piece of it:
|
|
10
|
+
* **a chunk must be able to say where it came from.** Not "which
|
|
11
|
+
* document, roughly" — which document, which characters of it, which
|
|
12
|
+
* page, under which heading. A passage the agent read and cannot
|
|
13
|
+
* locate is a passage nobody can check.
|
|
14
|
+
* Emits: N/A (types only).
|
|
15
|
+
*
|
|
16
|
+
* That is why `Chunk` carries offsets rather than only text, why `LoadedDocument`
|
|
17
|
+
* keeps per-page text rather than one flattened string, and why every loader
|
|
18
|
+
* is required to preserve positions rather than normalise them away.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/rag/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agentfootprint/rag — turning a folder of documents into something an agent
|
|
3
|
+
* can retrieve from.
|
|
4
|
+
*
|
|
5
|
+
* Loaders (text, Markdown, HTML, PDF), splitters, and the indexing chart that
|
|
6
|
+
* runs them: everything between "I have some documents" and "the vectors are
|
|
7
|
+
* in a store".
|
|
8
|
+
*
|
|
9
|
+
* ── Why this is its own door ────────────────────────────────────────────────
|
|
10
|
+
* Index time is a different PROCESS from run time. It happens at boot, on a
|
|
11
|
+
* cron, or from a CLI; it touches the filesystem; and for PDFs it reaches for
|
|
12
|
+
* an optional peer dependency. None of that belongs in the bundle of an agent
|
|
13
|
+
* that only wants to answer a question — a browser or edge runtime importing
|
|
14
|
+
* `agentfootprint` should never resolve `node:fs`. A door is the unit at which
|
|
15
|
+
* a bundler can cut, and this is the cut.
|
|
16
|
+
*
|
|
17
|
+
* ── `defineRAG` is NOT here, deliberately ───────────────────────────────────
|
|
18
|
+
* The retriever stays on the MAIN barrel, with `indexDocuments`, because it is
|
|
19
|
+
* run-time wiring: it is registered on an agent, it runs on every turn, and it
|
|
20
|
+
* belongs beside `defineTool` and the rest of the wiring surface. This door is
|
|
21
|
+
* the other half of the story — the half that runs once, before any agent
|
|
22
|
+
* exists.
|
|
23
|
+
*
|
|
24
|
+
* import { defineRAG, indexDocuments } from 'agentfootprint'; // wiring
|
|
25
|
+
* import { sqliteVectorStore } from 'agentfootprint/memory'; // where it lives
|
|
26
|
+
* import { indexFolder, byHeading } from 'agentfootprint/rag'; // building it
|
|
27
|
+
*
|
|
28
|
+
* ── Deferred, with destinations named ───────────────────────────────────────
|
|
29
|
+
* **Re-ranking and MMR** are retrieval-side concerns and belong behind
|
|
30
|
+
* `RetrievalStrategy` (`agentfootprint/memory`), not here — a re-ranker is a
|
|
31
|
+
* different rule for choosing among candidates, not a different way of
|
|
32
|
+
* building an index. **File watching** is deliberately absent: `indexCorpus`
|
|
33
|
+
* is an explicit call because magic that re-indexes behind you is magic that
|
|
34
|
+
* re-bills you. Run it at boot, from a cron, or from the CLI.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* import { indexFolder } from 'agentfootprint/rag';
|
|
39
|
+
* import { sqliteVectorStore } from 'agentfootprint/memory';
|
|
40
|
+
* import { staticEmbedder } from 'agentfootprint/providers';
|
|
41
|
+
*
|
|
42
|
+
* const report = await indexFolder('./docs', {
|
|
43
|
+
* to: sqliteVectorStore({ file: './corpus.db' }),
|
|
44
|
+
* embedder: staticEmbedder(),
|
|
45
|
+
* });
|
|
46
|
+
* // { discovered: 3, loaded: 3, chunks: 14, embedded: 14, skipped: 0, removed: 0, … }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export * from '../rag/index.js';
|
|
50
|
+
//# sourceMappingURL=rag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rag.d.ts","sourceRoot":"","sources":["../../../src/doors/rag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../../src/rag/hash.ts"],"names":[],"mappings":"AAcA,8CAA8C;AAC9C,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAMzD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rag/ — a folder of documents becomes an answering agent.
|
|
3
|
+
*
|
|
4
|
+
* @see ./types.ts the ports and the value objects
|
|
5
|
+
* @see ./loadDocuments.ts step 1 — bytes to text
|
|
6
|
+
* @see ./splitDocuments.ts step 2 — text to chunks that know where they came from
|
|
7
|
+
* @see ./indexCorpus.ts step 3 — the chart that embeds and stores them
|
|
8
|
+
*/
|
|
9
|
+
export { loadDocuments, type LoadDocumentsOptions, type LoadDocumentsResult, } from './loadDocuments.js';
|
|
10
|
+
export { splitDocuments, type SplitDocumentsOptions } from './splitDocuments.js';
|
|
11
|
+
export { indexCorpus, buildIndexChart, type IndexCorpusConfig } from './indexCorpus.js';
|
|
12
|
+
export { indexFolder, type IndexFolderOptions } from './indexFolder.js';
|
|
13
|
+
export { sha256 } from './hash.js';
|
|
14
|
+
export { DEFAULT_LOADERS, textLoader, markdownLoader, htmlLoader, pdfLoader, mockLoader, MissingPdfSupportError, type PdfLoaderOptions, type MockLoaderOptions, } from './loaders/index.js';
|
|
15
|
+
export { stripTags } from './loaders/html.js';
|
|
16
|
+
export { byParagraph, byHeading, fixedWithOverlap, wholeDocument, DEFAULT_MAX_CHARS, DEFAULT_OVERLAP_CHARS, type ByParagraphOptions, type ByHeadingOptions, type FixedWithOverlapOptions, } from './splitters/index.js';
|
|
17
|
+
export type { Chunk, DocumentInput, DocumentLoader, DocumentSource, FailedDocument, IndexReport, LoadedDocument, LoadedDocumentDraft, Splitter, SplitPiece, TruncatedChunk, } from './types.js';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/rag/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACxF,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,OAAO,EACL,eAAe,EACf,UAAU,EACV,cAAc,EACd,UAAU,EACV,SAAS,EACT,UAAU,EACV,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,OAAO,EACL,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,KAAK,EACL,aAAa,EACb,cAAc,EACd,cAAc,EACd,cAAc,EACd,WAAW,EACX,cAAc,EACd,mBAAmB,EACnB,QAAQ,EACR,UAAU,EACV,cAAc,GACf,MAAM,YAAY,CAAC"}
|