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.
Files changed (151) hide show
  1. package/AGENTS.md +2 -0
  2. package/CLAUDE.md +4 -0
  3. package/bin/agentfootprint-index.mjs +192 -0
  4. package/dist/doors/rag.js +66 -0
  5. package/dist/doors/rag.js.map +1 -0
  6. package/dist/esm/doors/rag.d.ts +49 -0
  7. package/dist/esm/doors/rag.js +50 -0
  8. package/dist/esm/doors/rag.js.map +1 -0
  9. package/dist/esm/rag/hash.d.ts +2 -0
  10. package/dist/esm/rag/hash.js +22 -0
  11. package/dist/esm/rag/hash.js.map +1 -0
  12. package/dist/esm/rag/index.d.ts +17 -0
  13. package/dist/esm/rag/index.js +17 -0
  14. package/dist/esm/rag/index.js.map +1 -0
  15. package/dist/esm/rag/indexCorpus.d.ts +102 -0
  16. package/dist/esm/rag/indexCorpus.js +339 -0
  17. package/dist/esm/rag/indexCorpus.js.map +1 -0
  18. package/dist/esm/rag/indexFolder.d.ts +40 -0
  19. package/dist/esm/rag/indexFolder.js +42 -0
  20. package/dist/esm/rag/indexFolder.js.map +1 -0
  21. package/dist/esm/rag/loadDocuments.d.ts +34 -0
  22. package/dist/esm/rag/loadDocuments.js +160 -0
  23. package/dist/esm/rag/loadDocuments.js.map +1 -0
  24. package/dist/esm/rag/loaders/html.d.ts +42 -0
  25. package/dist/esm/rag/loaders/html.js +48 -0
  26. package/dist/esm/rag/loaders/html.js.map +1 -0
  27. package/dist/esm/rag/loaders/index.d.ts +30 -0
  28. package/dist/esm/rag/loaders/index.js +24 -0
  29. package/dist/esm/rag/loaders/index.js.map +1 -0
  30. package/dist/esm/rag/loaders/markdown.d.ts +27 -0
  31. package/dist/esm/rag/loaders/markdown.js +12 -0
  32. package/dist/esm/rag/loaders/markdown.js.map +1 -0
  33. package/dist/esm/rag/loaders/mock.d.ts +28 -0
  34. package/dist/esm/rag/loaders/mock.js +14 -0
  35. package/dist/esm/rag/loaders/mock.js.map +1 -0
  36. package/dist/esm/rag/loaders/pdf.d.ts +39 -0
  37. package/dist/esm/rag/loaders/pdf.js +90 -0
  38. package/dist/esm/rag/loaders/pdf.js.map +1 -0
  39. package/dist/esm/rag/loaders/text.d.ts +23 -0
  40. package/dist/esm/rag/loaders/text.js +21 -0
  41. package/dist/esm/rag/loaders/text.js.map +1 -0
  42. package/dist/esm/rag/splitDocuments.d.ts +21 -0
  43. package/dist/esm/rag/splitDocuments.js +65 -0
  44. package/dist/esm/rag/splitDocuments.js.map +1 -0
  45. package/dist/esm/rag/splitters/byHeading.d.ts +36 -0
  46. package/dist/esm/rag/splitters/byHeading.js +66 -0
  47. package/dist/esm/rag/splitters/byHeading.js.map +1 -0
  48. package/dist/esm/rag/splitters/byParagraph.d.ts +24 -0
  49. package/dist/esm/rag/splitters/byParagraph.js +16 -0
  50. package/dist/esm/rag/splitters/byParagraph.js.map +1 -0
  51. package/dist/esm/rag/splitters/constants.d.ts +19 -0
  52. package/dist/esm/rag/splitters/constants.js +20 -0
  53. package/dist/esm/rag/splitters/constants.js.map +1 -0
  54. package/dist/esm/rag/splitters/fixedWithOverlap.d.ts +31 -0
  55. package/dist/esm/rag/splitters/fixedWithOverlap.js +34 -0
  56. package/dist/esm/rag/splitters/fixedWithOverlap.js.map +1 -0
  57. package/dist/esm/rag/splitters/index.d.ts +50 -0
  58. package/dist/esm/rag/splitters/index.js +51 -0
  59. package/dist/esm/rag/splitters/index.js.map +1 -0
  60. package/dist/esm/rag/splitters/shared.d.ts +87 -0
  61. package/dist/esm/rag/splitters/shared.js +188 -0
  62. package/dist/esm/rag/splitters/shared.js.map +1 -0
  63. package/dist/esm/rag/splitters/wholeDocument.d.ts +16 -0
  64. package/dist/esm/rag/splitters/wholeDocument.js +10 -0
  65. package/dist/esm/rag/splitters/wholeDocument.js.map +1 -0
  66. package/dist/esm/rag/types.d.ts +200 -0
  67. package/dist/esm/rag/types.js +20 -0
  68. package/dist/esm/rag/types.js.map +1 -0
  69. package/dist/rag/hash.js +26 -0
  70. package/dist/rag/hash.js.map +1 -0
  71. package/dist/rag/index.js +40 -0
  72. package/dist/rag/index.js.map +1 -0
  73. package/dist/rag/indexCorpus.js +344 -0
  74. package/dist/rag/indexCorpus.js.map +1 -0
  75. package/dist/rag/indexFolder.js +46 -0
  76. package/dist/rag/indexFolder.js.map +1 -0
  77. package/dist/rag/loadDocuments.js +164 -0
  78. package/dist/rag/loadDocuments.js.map +1 -0
  79. package/dist/rag/loaders/html.js +53 -0
  80. package/dist/rag/loaders/html.js.map +1 -0
  81. package/dist/rag/loaders/index.js +33 -0
  82. package/dist/rag/loaders/index.js.map +1 -0
  83. package/dist/rag/loaders/markdown.js +16 -0
  84. package/dist/rag/loaders/markdown.js.map +1 -0
  85. package/dist/rag/loaders/mock.js +18 -0
  86. package/dist/rag/loaders/mock.js.map +1 -0
  87. package/dist/rag/loaders/pdf.js +118 -0
  88. package/dist/rag/loaders/pdf.js.map +1 -0
  89. package/dist/rag/loaders/text.js +26 -0
  90. package/dist/rag/loaders/text.js.map +1 -0
  91. package/dist/rag/splitDocuments.js +69 -0
  92. package/dist/rag/splitDocuments.js.map +1 -0
  93. package/dist/rag/splitters/byHeading.js +70 -0
  94. package/dist/rag/splitters/byHeading.js.map +1 -0
  95. package/dist/rag/splitters/byParagraph.js +20 -0
  96. package/dist/rag/splitters/byParagraph.js.map +1 -0
  97. package/dist/rag/splitters/constants.js +23 -0
  98. package/dist/rag/splitters/constants.js.map +1 -0
  99. package/dist/rag/splitters/fixedWithOverlap.js +38 -0
  100. package/dist/rag/splitters/fixedWithOverlap.js.map +1 -0
  101. package/dist/rag/splitters/index.js +60 -0
  102. package/dist/rag/splitters/index.js.map +1 -0
  103. package/dist/rag/splitters/shared.js +199 -0
  104. package/dist/rag/splitters/shared.js.map +1 -0
  105. package/dist/rag/splitters/wholeDocument.js +14 -0
  106. package/dist/rag/splitters/wholeDocument.js.map +1 -0
  107. package/dist/rag/types.js +21 -0
  108. package/dist/rag/types.js.map +1 -0
  109. package/dist/types/doors/rag.d.ts +50 -0
  110. package/dist/types/doors/rag.d.ts.map +1 -0
  111. package/dist/types/rag/hash.d.ts +3 -0
  112. package/dist/types/rag/hash.d.ts.map +1 -0
  113. package/dist/types/rag/index.d.ts +18 -0
  114. package/dist/types/rag/index.d.ts.map +1 -0
  115. package/dist/types/rag/indexCorpus.d.ts +103 -0
  116. package/dist/types/rag/indexCorpus.d.ts.map +1 -0
  117. package/dist/types/rag/indexFolder.d.ts +41 -0
  118. package/dist/types/rag/indexFolder.d.ts.map +1 -0
  119. package/dist/types/rag/loadDocuments.d.ts +35 -0
  120. package/dist/types/rag/loadDocuments.d.ts.map +1 -0
  121. package/dist/types/rag/loaders/html.d.ts +43 -0
  122. package/dist/types/rag/loaders/html.d.ts.map +1 -0
  123. package/dist/types/rag/loaders/index.d.ts +31 -0
  124. package/dist/types/rag/loaders/index.d.ts.map +1 -0
  125. package/dist/types/rag/loaders/markdown.d.ts +28 -0
  126. package/dist/types/rag/loaders/markdown.d.ts.map +1 -0
  127. package/dist/types/rag/loaders/mock.d.ts +29 -0
  128. package/dist/types/rag/loaders/mock.d.ts.map +1 -0
  129. package/dist/types/rag/loaders/pdf.d.ts +40 -0
  130. package/dist/types/rag/loaders/pdf.d.ts.map +1 -0
  131. package/dist/types/rag/loaders/text.d.ts +24 -0
  132. package/dist/types/rag/loaders/text.d.ts.map +1 -0
  133. package/dist/types/rag/splitDocuments.d.ts +22 -0
  134. package/dist/types/rag/splitDocuments.d.ts.map +1 -0
  135. package/dist/types/rag/splitters/byHeading.d.ts +37 -0
  136. package/dist/types/rag/splitters/byHeading.d.ts.map +1 -0
  137. package/dist/types/rag/splitters/byParagraph.d.ts +25 -0
  138. package/dist/types/rag/splitters/byParagraph.d.ts.map +1 -0
  139. package/dist/types/rag/splitters/constants.d.ts +20 -0
  140. package/dist/types/rag/splitters/constants.d.ts.map +1 -0
  141. package/dist/types/rag/splitters/fixedWithOverlap.d.ts +32 -0
  142. package/dist/types/rag/splitters/fixedWithOverlap.d.ts.map +1 -0
  143. package/dist/types/rag/splitters/index.d.ts +51 -0
  144. package/dist/types/rag/splitters/index.d.ts.map +1 -0
  145. package/dist/types/rag/splitters/shared.d.ts +88 -0
  146. package/dist/types/rag/splitters/shared.d.ts.map +1 -0
  147. package/dist/types/rag/splitters/wholeDocument.d.ts +17 -0
  148. package/dist/types/rag/splitters/wholeDocument.d.ts.map +1 -0
  149. package/dist/types/rag/types.d.ts +201 -0
  150. package/dist/types/rag/types.d.ts.map +1 -0
  151. 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,3 @@
1
+ /** Hex sha-256 of the bytes or text given. */
2
+ export declare function sha256(input: Uint8Array | string): string;
3
+ //# sourceMappingURL=hash.d.ts.map
@@ -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"}