@convex-dev/rag 0.1.7

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 (113) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +371 -0
  3. package/dist/client/_generated/_ignore.d.ts +1 -0
  4. package/dist/client/_generated/_ignore.d.ts.map +1 -0
  5. package/dist/client/_generated/_ignore.js +3 -0
  6. package/dist/client/_generated/_ignore.js.map +1 -0
  7. package/dist/client/defaultChunker.d.ts +15 -0
  8. package/dist/client/defaultChunker.d.ts.map +1 -0
  9. package/dist/client/defaultChunker.js +148 -0
  10. package/dist/client/defaultChunker.js.map +1 -0
  11. package/dist/client/fileUtils.d.ts +24 -0
  12. package/dist/client/fileUtils.d.ts.map +1 -0
  13. package/dist/client/fileUtils.js +179 -0
  14. package/dist/client/fileUtils.js.map +1 -0
  15. package/dist/client/index.d.ts +442 -0
  16. package/dist/client/index.d.ts.map +1 -0
  17. package/dist/client/index.js +597 -0
  18. package/dist/client/index.js.map +1 -0
  19. package/dist/client/types.d.ts +29 -0
  20. package/dist/client/types.d.ts.map +1 -0
  21. package/dist/client/types.js +2 -0
  22. package/dist/client/types.js.map +1 -0
  23. package/dist/component/_generated/api.d.ts +439 -0
  24. package/dist/component/_generated/api.d.ts.map +1 -0
  25. package/dist/component/_generated/api.js +22 -0
  26. package/dist/component/_generated/api.js.map +1 -0
  27. package/dist/component/_generated/dataModel.d.ts +60 -0
  28. package/dist/component/_generated/server.d.ts +149 -0
  29. package/dist/component/_generated/server.d.ts.map +1 -0
  30. package/dist/component/_generated/server.js +74 -0
  31. package/dist/component/_generated/server.js.map +1 -0
  32. package/dist/component/chunks.d.ts +139 -0
  33. package/dist/component/chunks.d.ts.map +1 -0
  34. package/dist/component/chunks.js +413 -0
  35. package/dist/component/chunks.js.map +1 -0
  36. package/dist/component/convex.config.d.ts +3 -0
  37. package/dist/component/convex.config.d.ts.map +1 -0
  38. package/dist/component/convex.config.js +6 -0
  39. package/dist/component/convex.config.js.map +1 -0
  40. package/dist/component/embeddings/importance.d.ts +21 -0
  41. package/dist/component/embeddings/importance.d.ts.map +1 -0
  42. package/dist/component/embeddings/importance.js +67 -0
  43. package/dist/component/embeddings/importance.js.map +1 -0
  44. package/dist/component/embeddings/index.d.ts +23 -0
  45. package/dist/component/embeddings/index.d.ts.map +1 -0
  46. package/dist/component/embeddings/index.js +54 -0
  47. package/dist/component/embeddings/index.js.map +1 -0
  48. package/dist/component/embeddings/tables.d.ts +39 -0
  49. package/dist/component/embeddings/tables.d.ts.map +1 -0
  50. package/dist/component/embeddings/tables.js +53 -0
  51. package/dist/component/embeddings/tables.js.map +1 -0
  52. package/dist/component/entries.d.ts +167 -0
  53. package/dist/component/entries.d.ts.map +1 -0
  54. package/dist/component/entries.js +409 -0
  55. package/dist/component/entries.js.map +1 -0
  56. package/dist/component/filters.d.ts +46 -0
  57. package/dist/component/filters.d.ts.map +1 -0
  58. package/dist/component/filters.js +72 -0
  59. package/dist/component/filters.js.map +1 -0
  60. package/dist/component/namespaces.d.ts +131 -0
  61. package/dist/component/namespaces.d.ts.map +1 -0
  62. package/dist/component/namespaces.js +222 -0
  63. package/dist/component/namespaces.js.map +1 -0
  64. package/dist/component/schema.d.ts +1697 -0
  65. package/dist/component/schema.d.ts.map +1 -0
  66. package/dist/component/schema.js +88 -0
  67. package/dist/component/schema.js.map +1 -0
  68. package/dist/component/search.d.ts +20 -0
  69. package/dist/component/search.d.ts.map +1 -0
  70. package/dist/component/search.js +69 -0
  71. package/dist/component/search.js.map +1 -0
  72. package/dist/package.json +3 -0
  73. package/dist/react/index.d.ts +2 -0
  74. package/dist/react/index.d.ts.map +1 -0
  75. package/dist/react/index.js +6 -0
  76. package/dist/react/index.js.map +1 -0
  77. package/dist/shared.d.ts +479 -0
  78. package/dist/shared.d.ts.map +1 -0
  79. package/dist/shared.js +98 -0
  80. package/dist/shared.js.map +1 -0
  81. package/package.json +97 -0
  82. package/src/client/_generated/_ignore.ts +1 -0
  83. package/src/client/defaultChunker.test.ts +243 -0
  84. package/src/client/defaultChunker.ts +183 -0
  85. package/src/client/fileUtils.ts +179 -0
  86. package/src/client/index.test.ts +475 -0
  87. package/src/client/index.ts +1125 -0
  88. package/src/client/setup.test.ts +28 -0
  89. package/src/client/types.ts +69 -0
  90. package/src/component/_generated/api.d.ts +439 -0
  91. package/src/component/_generated/api.js +23 -0
  92. package/src/component/_generated/dataModel.d.ts +60 -0
  93. package/src/component/_generated/server.d.ts +149 -0
  94. package/src/component/_generated/server.js +90 -0
  95. package/src/component/chunks.test.ts +915 -0
  96. package/src/component/chunks.ts +555 -0
  97. package/src/component/convex.config.ts +7 -0
  98. package/src/component/embeddings/importance.test.ts +249 -0
  99. package/src/component/embeddings/importance.ts +75 -0
  100. package/src/component/embeddings/index.test.ts +482 -0
  101. package/src/component/embeddings/index.ts +99 -0
  102. package/src/component/embeddings/tables.ts +114 -0
  103. package/src/component/entries.test.ts +341 -0
  104. package/src/component/entries.ts +546 -0
  105. package/src/component/filters.ts +119 -0
  106. package/src/component/namespaces.ts +299 -0
  107. package/src/component/schema.ts +106 -0
  108. package/src/component/search.test.ts +445 -0
  109. package/src/component/search.ts +97 -0
  110. package/src/component/setup.test.ts +5 -0
  111. package/src/react/index.ts +7 -0
  112. package/src/shared.ts +247 -0
  113. package/src/vitest.config.ts +7 -0
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Chunk text for embedding.
3
+ *
4
+ * By default, it will chunk into paragraphs and target
5
+ * 200-2000 characters per chunk (only less than 1 line if the hard limit is reached).
6
+ */
7
+ export function defaultChunker(text, { minLines = 1, minCharsSoftLimit = 200, maxCharsSoftLimit = 2000, maxCharsHardLimit = 10000, delimiter = "\n\n", } = {}) {
8
+ if (!text)
9
+ return [];
10
+ // Split text into individual lines
11
+ const lines = text.split("\n");
12
+ const chunks = [];
13
+ let currentChunk = [];
14
+ for (let i = 0; i < lines.length; i++) {
15
+ const line = lines[i];
16
+ // Check if this line starts a new section (based on delimiter pattern)
17
+ const isNewSection = shouldStartNewSection(lines, i, delimiter);
18
+ // Calculate potential chunk if we add this line
19
+ const potentialChunk = [...currentChunk, line].join("\n");
20
+ // If adding this line would exceed max chars, finalize current chunk first
21
+ if (potentialChunk.length > maxCharsSoftLimit && currentChunk.length > 0) {
22
+ const trimmedChunk = removeTrailingEmptyLines(currentChunk);
23
+ chunks.push(trimmedChunk.join("\n"));
24
+ // Split the line if it exceeds hard limit
25
+ const splitLines = maybeSplitLine(line, maxCharsHardLimit);
26
+ // Add all but the last split piece as separate chunks
27
+ for (let j = 0; j < splitLines.length - 1; j++) {
28
+ chunks.push(splitLines[j]);
29
+ }
30
+ // Keep the last piece for potential combination with next lines
31
+ currentChunk = [splitLines[splitLines.length - 1]];
32
+ continue;
33
+ }
34
+ // If we're starting a new section and current chunk meets minimum requirements
35
+ if (isNewSection &&
36
+ currentChunk.length >= minLines &&
37
+ currentChunk.join("\n").length >= Math.min(minCharsSoftLimit * 0.8, 150)) {
38
+ // Simple logic: only split if potential chunk would exceed the soft max limit
39
+ if (potentialChunk.length > maxCharsSoftLimit) {
40
+ // When splitting at delimiter boundary, preserve natural empty lines (don't remove trailing empty lines)
41
+ chunks.push(currentChunk.join("\n"));
42
+ currentChunk = [line];
43
+ continue;
44
+ }
45
+ }
46
+ // Add line to current chunk
47
+ currentChunk.push(line);
48
+ // If current chunk is too big, split it
49
+ if (currentChunk.join("\n").length > maxCharsSoftLimit) {
50
+ if (currentChunk.length === 1) {
51
+ // Single line too long - split it if it exceeds hard limit
52
+ const splitLines = maybeSplitLine(line, maxCharsHardLimit);
53
+ if (splitLines.length > 1) {
54
+ // Line was split - add all but the last piece as separate chunks
55
+ for (let j = 0; j < splitLines.length - 1; j++) {
56
+ chunks.push(splitLines[j]);
57
+ }
58
+ // Keep the last piece for potential combination with next lines
59
+ currentChunk = [splitLines[splitLines.length - 1]];
60
+ }
61
+ else {
62
+ // Line doesn't exceed hard limit, keep it as is
63
+ chunks.push(line);
64
+ currentChunk = [];
65
+ }
66
+ }
67
+ else {
68
+ // Remove last line and finalize chunk
69
+ const lastLine = currentChunk.pop();
70
+ const trimmedChunk = removeTrailingEmptyLines(currentChunk);
71
+ chunks.push(trimmedChunk.join("\n"));
72
+ currentChunk = [lastLine];
73
+ }
74
+ }
75
+ }
76
+ // Add remaining chunk, splitting if it exceeds hard limit
77
+ if (currentChunk.length > 0) {
78
+ const remainingText = currentChunk.join("\n");
79
+ if (remainingText.length > maxCharsHardLimit) {
80
+ // Split the remaining chunk if it exceeds hard limit
81
+ const splitLines = maybeSplitLine(remainingText, maxCharsHardLimit);
82
+ chunks.push(...splitLines);
83
+ }
84
+ else {
85
+ const trimmedChunk = removeTrailingEmptyLines(currentChunk);
86
+ chunks.push(trimmedChunk.join("\n"));
87
+ }
88
+ }
89
+ return chunks;
90
+ }
91
+ function maybeSplitLine(line, maxCharsHardLimit) {
92
+ const inputs = [line]; // in reverse order
93
+ const lines = [];
94
+ while (inputs.length > 0) {
95
+ const input = inputs.pop();
96
+ if (input.length <= maxCharsHardLimit) {
97
+ lines.push(input);
98
+ continue;
99
+ }
100
+ // split it in half
101
+ const splitIndex = Math.floor(input.length / 2);
102
+ const candidate = input.slice(0, splitIndex);
103
+ const rest = input.slice(splitIndex);
104
+ if (candidate.length < maxCharsHardLimit) {
105
+ lines.push(candidate, rest);
106
+ }
107
+ else {
108
+ inputs.push(rest, candidate);
109
+ }
110
+ }
111
+ return lines;
112
+ }
113
+ function shouldStartNewSection(lines, index, delimiter) {
114
+ if (index === 0)
115
+ return false;
116
+ // For default "\n\n" delimiter, check for blank lines
117
+ if (delimiter === "\n\n") {
118
+ return lines[index - 1] === "";
119
+ }
120
+ // For custom delimiters, check if previous lines match the delimiter pattern
121
+ const delimiterLines = delimiter.split("\n");
122
+ if (delimiterLines.length <= 1)
123
+ return false;
124
+ // Check if the delimiter pattern appears before this line
125
+ for (let i = 0; i < delimiterLines.length - 1; i++) {
126
+ const checkIndex = index - delimiterLines.length + 1 + i;
127
+ if (checkIndex < 0 || lines[checkIndex] !== delimiterLines[i]) {
128
+ return false;
129
+ }
130
+ }
131
+ return true;
132
+ }
133
+ function removeTrailingEmptyLines(lines) {
134
+ // Don't remove anything if there's only one line
135
+ if (lines.length <= 1) {
136
+ return lines;
137
+ }
138
+ // Find the last non-empty line
139
+ for (let i = lines.length - 1; i >= 0; i--) {
140
+ if (lines[i].trim() !== "") {
141
+ return lines.slice(0, i + 1);
142
+ }
143
+ }
144
+ // If all lines are empty, keep at least one
145
+ return lines.length > 0 ? [lines[0]] : [];
146
+ }
147
+ export default defaultChunker;
148
+ //# sourceMappingURL=defaultChunker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaultChunker.js","sourceRoot":"","sources":["../../src/client/defaultChunker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export declare function guessMimeTypeFromExtension(filename: string): string | undefined;
2
+ /**
3
+ * Return a best-guess MIME type based on the magic-number signature
4
+ * found at the start of an ArrayBuffer.
5
+ *
6
+ * @param buf – the source ArrayBuffer
7
+ * @returns the detected MIME type, or `"application/octet-stream"` if unknown
8
+ */
9
+ export declare function guessMimeTypeFromContents(buf: ArrayBuffer | string): string;
10
+ /**
11
+ * Make a contentHash of a Blob that matches the File Storage metadata, allowing
12
+ * identifying when content is identical.
13
+ * @param blob The contents to hash
14
+ * @returns sha256 hash of the contents
15
+ */
16
+ export declare function contentHashFromArrayBuffer(buffer: ArrayBuffer): Promise<string>;
17
+ /**
18
+ * Split a filename into a keyword-friendly string. Specifically adds sections
19
+ * of camelCase and TitleCase into a space-separated strings.
20
+ * e.g. "MyFile is soGreat.txt" -> "MyFile is soGreat.txt My File so Great"
21
+ * Note: it doesn't split up titles that don't have a file extension.
22
+ */
23
+ export declare function splitFilename(title: string | undefined): string | undefined;
24
+ //# sourceMappingURL=fileUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileUtils.d.ts","sourceRoot":"","sources":["../../src/client/fileUtils.ts"],"names":[],"mappings":"AAAA,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,SAAS,CA6DpB;AACD;;;;;;GAMG;AAEH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,GAAG,MAAM,CA2D3E;AACD;;;;;GAKG;AAEH,wBAAsB,0BAA0B,CAAC,MAAM,EAAE,WAAW,mBAMnE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAyB3E"}
@@ -0,0 +1,179 @@
1
+ export function guessMimeTypeFromExtension(filename) {
2
+ const extension = filename.split(".").pop();
3
+ if (!extension || extension.includes(" ")) {
4
+ return undefined;
5
+ }
6
+ switch (extension.toLowerCase()) {
7
+ case "pdf":
8
+ return "application/pdf";
9
+ case "txt":
10
+ case "rtf":
11
+ return "text/plain";
12
+ case "json":
13
+ return "application/json";
14
+ case "xml":
15
+ return "application/xml";
16
+ case "html":
17
+ return "text/html";
18
+ case "css":
19
+ return "text/css";
20
+ case "js":
21
+ case "cjs":
22
+ case "mjs":
23
+ case "jsx":
24
+ case "ts":
25
+ case "tsx":
26
+ return "text/javascript";
27
+ case "md":
28
+ case "mdx":
29
+ return "text/markdown";
30
+ case "csv":
31
+ return "text/csv";
32
+ case "zip":
33
+ return "application/zip";
34
+ case "apng":
35
+ return "image/apng";
36
+ case "png":
37
+ return "image/png";
38
+ case "avif":
39
+ return "image/avif";
40
+ case "gif":
41
+ return "image/gif";
42
+ case "svg":
43
+ return "image/svg+xml";
44
+ case "webp":
45
+ return "image/webp";
46
+ case "tiff":
47
+ return "image/tiff";
48
+ case "ico":
49
+ return "image/x-icon";
50
+ case "jpeg":
51
+ case "jpg":
52
+ return "image/jpeg";
53
+ case "mp1":
54
+ case "mp2":
55
+ case "mp3":
56
+ return "audio/mpeg";
57
+ case "mp4":
58
+ return "video/mp4";
59
+ default:
60
+ return "application/octet-stream";
61
+ }
62
+ }
63
+ /**
64
+ * Return a best-guess MIME type based on the magic-number signature
65
+ * found at the start of an ArrayBuffer.
66
+ *
67
+ * @param buf – the source ArrayBuffer
68
+ * @returns the detected MIME type, or `"application/octet-stream"` if unknown
69
+ */
70
+ export function guessMimeTypeFromContents(buf) {
71
+ if (typeof buf === "string") {
72
+ if (buf.match(/^data:\w+\/\w+;base64/)) {
73
+ return buf.split(";")[0].split(":")[1];
74
+ }
75
+ return "text/plain";
76
+ }
77
+ if (buf.byteLength < 4)
78
+ return "application/octet-stream";
79
+ // Read the first 12 bytes (enough for all signatures below)
80
+ const bytes = new Uint8Array(buf.slice(0, 12));
81
+ const hex = [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
82
+ // Helper so we can look at only the needed prefix
83
+ const startsWith = (sig) => hex.startsWith(sig.toLowerCase());
84
+ // --- image formats ---
85
+ if (startsWith("89504e47"))
86
+ return "image/png"; // PNG - 89 50 4E 47
87
+ if (startsWith("ffd8ffdb") ||
88
+ startsWith("ffd8ffe0") ||
89
+ startsWith("ffd8ffee") ||
90
+ startsWith("ffd8ffe1"))
91
+ return "image/jpeg"; // JPEG
92
+ if (startsWith("47494638"))
93
+ return "image/gif"; // GIF
94
+ if (startsWith("424d"))
95
+ return "image/bmp"; // BMP
96
+ if (startsWith("52494646") && hex.substr(16, 8) === "57454250")
97
+ return "image/webp"; // WEBP (RIFF....WEBP)
98
+ if (startsWith("49492a00"))
99
+ return "image/tiff"; // TIFF
100
+ // <svg in hex is 3c 3f 78 6d 6c
101
+ if (startsWith("3c737667"))
102
+ return "image/svg+xml"; // <svg
103
+ if (startsWith("3c3f786d"))
104
+ return "image/svg+xml"; // <?xm
105
+ // --- audio/video ---
106
+ if (startsWith("494433"))
107
+ return "audio/mpeg"; // MP3 (ID3)
108
+ if (startsWith("000001ba") || startsWith("000001b3"))
109
+ return "video/mpeg"; // MPEG container
110
+ if (startsWith("1a45dfa3"))
111
+ return "video/webm"; // WEBM / Matroska
112
+ if (startsWith("00000018") && hex.substr(16, 8) === "66747970")
113
+ return "video/mp4"; // MP4
114
+ if (startsWith("4f676753"))
115
+ return "audio/ogg"; // OGG / Opus
116
+ // --- documents & archives ---
117
+ if (startsWith("25504446"))
118
+ return "application/pdf"; // PDF
119
+ if (startsWith("504b0304") ||
120
+ startsWith("504b0506") ||
121
+ startsWith("504b0708"))
122
+ return "application/zip"; // ZIP / DOCX / PPTX / XLSX / EPUB
123
+ if (startsWith("52617221"))
124
+ return "application/x-rar-compressed"; // RAR
125
+ if (startsWith("7f454c46"))
126
+ return "application/x-elf"; // ELF binaries
127
+ if (startsWith("1f8b08"))
128
+ return "application/gzip"; // GZIP
129
+ if (startsWith("425a68"))
130
+ return "application/x-bzip2"; // BZIP2
131
+ if (startsWith("3c3f786d6c"))
132
+ return "application/xml"; // XML
133
+ // Plain text, JSON and others are trickier—fallback:
134
+ return "application/octet-stream";
135
+ }
136
+ /**
137
+ * Make a contentHash of a Blob that matches the File Storage metadata, allowing
138
+ * identifying when content is identical.
139
+ * @param blob The contents to hash
140
+ * @returns sha256 hash of the contents
141
+ */
142
+ export async function contentHashFromArrayBuffer(buffer) {
143
+ return Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256", buffer)))
144
+ .map((b) => b.toString(16).padStart(2, "0"))
145
+ .join("");
146
+ }
147
+ /**
148
+ * Split a filename into a keyword-friendly string. Specifically adds sections
149
+ * of camelCase and TitleCase into a space-separated strings.
150
+ * e.g. "MyFile is soGreat.txt" -> "MyFile is soGreat.txt My File so Great"
151
+ * Note: it doesn't split up titles that don't have a file extension.
152
+ */
153
+ export function splitFilename(title) {
154
+ if (!title) {
155
+ return undefined;
156
+ }
157
+ const parts = title.split(".");
158
+ if (parts.pop()?.includes(" ")) {
159
+ // There isn't an extension, so don't treat it as a filename
160
+ return title;
161
+ }
162
+ // split up camelCase into "camel Case"
163
+ return [
164
+ title,
165
+ ...parts.flatMap((part) => {
166
+ const words = part.split(" ");
167
+ const camelCaseWords = words.flatMap((word) => {
168
+ const pieces = word.split(/(?=[A-Z])/);
169
+ if (pieces.length === 1) {
170
+ // This will already be verbatim in the regular title parts
171
+ return [];
172
+ }
173
+ return pieces;
174
+ });
175
+ return camelCaseWords;
176
+ }),
177
+ ].join(" ");
178
+ }
179
+ //# sourceMappingURL=fileUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileUtils.js","sourceRoot":"","sources":["../../src/client/fileUtils.ts"],"names":[],"mappings":"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"}