@ssmeo/mcp-local-rag 0.18.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/LICENSE +21 -0
  2. package/README.de.md +441 -0
  3. package/README.es.md +441 -0
  4. package/README.fr.md +441 -0
  5. package/README.md +530 -0
  6. package/README.pt-BR.md +441 -0
  7. package/README.zh-CN.md +441 -0
  8. package/dist/bin/install-skills.d.ts +19 -0
  9. package/dist/bin/install-skills.d.ts.map +1 -0
  10. package/dist/bin/install-skills.js +218 -0
  11. package/dist/bin/install-skills.js.map +1 -0
  12. package/dist/chunker/index.d.ts +24 -0
  13. package/dist/chunker/index.d.ts.map +1 -0
  14. package/dist/chunker/index.js +2 -0
  15. package/dist/chunker/index.js.map +1 -0
  16. package/dist/chunker/semantic-chunker.d.ts +96 -0
  17. package/dist/chunker/semantic-chunker.d.ts.map +1 -0
  18. package/dist/chunker/semantic-chunker.js +362 -0
  19. package/dist/chunker/semantic-chunker.js.map +1 -0
  20. package/dist/chunker/sentence-splitter.d.ts +32 -0
  21. package/dist/chunker/sentence-splitter.d.ts.map +1 -0
  22. package/dist/chunker/sentence-splitter.js +231 -0
  23. package/dist/chunker/sentence-splitter.js.map +1 -0
  24. package/dist/chunker/token-containment.d.ts +39 -0
  25. package/dist/chunker/token-containment.d.ts.map +1 -0
  26. package/dist/chunker/token-containment.js +83 -0
  27. package/dist/chunker/token-containment.js.map +1 -0
  28. package/dist/cli/common.d.ts +34 -0
  29. package/dist/cli/common.d.ts.map +1 -0
  30. package/dist/cli/common.js +121 -0
  31. package/dist/cli/common.js.map +1 -0
  32. package/dist/cli/delete.d.ts +3 -0
  33. package/dist/cli/delete.d.ts.map +1 -0
  34. package/dist/cli/delete.js +169 -0
  35. package/dist/cli/delete.js.map +1 -0
  36. package/dist/cli/file-collection.d.ts +2 -0
  37. package/dist/cli/file-collection.d.ts.map +1 -0
  38. package/dist/cli/file-collection.js +53 -0
  39. package/dist/cli/file-collection.js.map +1 -0
  40. package/dist/cli/ingest.d.ts +69 -0
  41. package/dist/cli/ingest.d.ts.map +1 -0
  42. package/dist/cli/ingest.js +323 -0
  43. package/dist/cli/ingest.js.map +1 -0
  44. package/dist/cli/list.d.ts +27 -0
  45. package/dist/cli/list.d.ts.map +1 -0
  46. package/dist/cli/list.js +207 -0
  47. package/dist/cli/list.js.map +1 -0
  48. package/dist/cli/options.d.ts +89 -0
  49. package/dist/cli/options.d.ts.map +1 -0
  50. package/dist/cli/options.js +244 -0
  51. package/dist/cli/options.js.map +1 -0
  52. package/dist/cli/query.d.ts +17 -0
  53. package/dist/cli/query.d.ts.map +1 -0
  54. package/dist/cli/query.js +194 -0
  55. package/dist/cli/query.js.map +1 -0
  56. package/dist/cli/read-neighbors.d.ts +3 -0
  57. package/dist/cli/read-neighbors.d.ts.map +1 -0
  58. package/dist/cli/read-neighbors.js +192 -0
  59. package/dist/cli/read-neighbors.js.map +1 -0
  60. package/dist/cli/status.d.ts +6 -0
  61. package/dist/cli/status.d.ts.map +1 -0
  62. package/dist/cli/status.js +78 -0
  63. package/dist/cli/status.js.map +1 -0
  64. package/dist/cli/sync.d.ts +6 -0
  65. package/dist/cli/sync.d.ts.map +1 -0
  66. package/dist/cli/sync.js +271 -0
  67. package/dist/cli/sync.js.map +1 -0
  68. package/dist/cli-main.d.ts +9 -0
  69. package/dist/cli-main.d.ts.map +1 -0
  70. package/dist/cli-main.js +60 -0
  71. package/dist/cli-main.js.map +1 -0
  72. package/dist/embedder/index.d.ts +143 -0
  73. package/dist/embedder/index.d.ts.map +1 -0
  74. package/dist/embedder/index.js +429 -0
  75. package/dist/embedder/index.js.map +1 -0
  76. package/dist/embedder/remote.d.ts +51 -0
  77. package/dist/embedder/remote.d.ts.map +1 -0
  78. package/dist/embedder/remote.js +182 -0
  79. package/dist/embedder/remote.js.map +1 -0
  80. package/dist/features/list.d.ts +37 -0
  81. package/dist/features/list.d.ts.map +1 -0
  82. package/dist/features/list.js +41 -0
  83. package/dist/features/list.js.map +1 -0
  84. package/dist/features/sync.d.ts +219 -0
  85. package/dist/features/sync.d.ts.map +1 -0
  86. package/dist/features/sync.js +461 -0
  87. package/dist/features/sync.js.map +1 -0
  88. package/dist/index.d.ts +3 -0
  89. package/dist/index.d.ts.map +1 -0
  90. package/dist/index.js +56 -0
  91. package/dist/index.js.map +1 -0
  92. package/dist/ingest/compute.d.ts +63 -0
  93. package/dist/ingest/compute.d.ts.map +1 -0
  94. package/dist/ingest/compute.js +161 -0
  95. package/dist/ingest/compute.js.map +1 -0
  96. package/dist/ingest/file.d.ts +40 -0
  97. package/dist/ingest/file.d.ts.map +1 -0
  98. package/dist/ingest/file.js +74 -0
  99. package/dist/ingest/file.js.map +1 -0
  100. package/dist/ingest/visual.d.ts +52 -0
  101. package/dist/ingest/visual.d.ts.map +1 -0
  102. package/dist/ingest/visual.js +294 -0
  103. package/dist/ingest/visual.js.map +1 -0
  104. package/dist/parser/docx-parser.d.ts +12 -0
  105. package/dist/parser/docx-parser.d.ts.map +1 -0
  106. package/dist/parser/docx-parser.js +375 -0
  107. package/dist/parser/docx-parser.js.map +1 -0
  108. package/dist/parser/html-parser.d.ts +16 -0
  109. package/dist/parser/html-parser.d.ts.map +1 -0
  110. package/dist/parser/html-parser.js +119 -0
  111. package/dist/parser/html-parser.js.map +1 -0
  112. package/dist/parser/index.d.ts +125 -0
  113. package/dist/parser/index.d.ts.map +1 -0
  114. package/dist/parser/index.js +364 -0
  115. package/dist/parser/index.js.map +1 -0
  116. package/dist/parser/pdf-extract.d.ts +49 -0
  117. package/dist/parser/pdf-extract.d.ts.map +1 -0
  118. package/dist/parser/pdf-extract.js +114 -0
  119. package/dist/parser/pdf-extract.js.map +1 -0
  120. package/dist/parser/pdf-filter.d.ts +91 -0
  121. package/dist/parser/pdf-filter.d.ts.map +1 -0
  122. package/dist/parser/pdf-filter.js +522 -0
  123. package/dist/parser/pdf-filter.js.map +1 -0
  124. package/dist/parser/title-extractor.d.ts +28 -0
  125. package/dist/parser/title-extractor.d.ts.map +1 -0
  126. package/dist/parser/title-extractor.js +105 -0
  127. package/dist/parser/title-extractor.js.map +1 -0
  128. package/dist/pdf-visual/captioner.d.ts +11 -0
  129. package/dist/pdf-visual/captioner.d.ts.map +1 -0
  130. package/dist/pdf-visual/captioner.js +48 -0
  131. package/dist/pdf-visual/captioner.js.map +1 -0
  132. package/dist/pdf-visual/captioners/fast.d.ts +7 -0
  133. package/dist/pdf-visual/captioners/fast.d.ts.map +1 -0
  134. package/dist/pdf-visual/captioners/fast.js +108 -0
  135. package/dist/pdf-visual/captioners/fast.js.map +1 -0
  136. package/dist/pdf-visual/captioners/quality.d.ts +7 -0
  137. package/dist/pdf-visual/captioners/quality.d.ts.map +1 -0
  138. package/dist/pdf-visual/captioners/quality.js +101 -0
  139. package/dist/pdf-visual/captioners/quality.js.map +1 -0
  140. package/dist/pdf-visual/captioners/shared.d.ts +81 -0
  141. package/dist/pdf-visual/captioners/shared.d.ts.map +1 -0
  142. package/dist/pdf-visual/captioners/shared.js +156 -0
  143. package/dist/pdf-visual/captioners/shared.js.map +1 -0
  144. package/dist/pdf-visual/detector.d.ts +9 -0
  145. package/dist/pdf-visual/detector.d.ts.map +1 -0
  146. package/dist/pdf-visual/detector.js +269 -0
  147. package/dist/pdf-visual/detector.js.map +1 -0
  148. package/dist/pdf-visual/index.d.ts +13 -0
  149. package/dist/pdf-visual/index.d.ts.map +1 -0
  150. package/dist/pdf-visual/index.js +53 -0
  151. package/dist/pdf-visual/index.js.map +1 -0
  152. package/dist/pdf-visual/renderer.d.ts +9 -0
  153. package/dist/pdf-visual/renderer.d.ts.map +1 -0
  154. package/dist/pdf-visual/renderer.js +186 -0
  155. package/dist/pdf-visual/renderer.js.map +1 -0
  156. package/dist/pdf-visual/types.d.ts +53 -0
  157. package/dist/pdf-visual/types.d.ts.map +1 -0
  158. package/dist/pdf-visual/types.js +17 -0
  159. package/dist/pdf-visual/types.js.map +1 -0
  160. package/dist/server/error-utils.d.ts +63 -0
  161. package/dist/server/error-utils.d.ts.map +1 -0
  162. package/dist/server/error-utils.js +124 -0
  163. package/dist/server/error-utils.js.map +1 -0
  164. package/dist/server/index.d.ts +216 -0
  165. package/dist/server/index.d.ts.map +1 -0
  166. package/dist/server/index.js +1068 -0
  167. package/dist/server/index.js.map +1 -0
  168. package/dist/server/list-scanner.d.ts +30 -0
  169. package/dist/server/list-scanner.d.ts.map +1 -0
  170. package/dist/server/list-scanner.js +50 -0
  171. package/dist/server/list-scanner.js.map +1 -0
  172. package/dist/server/tool-definitions.d.ts +8 -0
  173. package/dist/server/tool-definitions.d.ts.map +1 -0
  174. package/dist/server/tool-definitions.js +181 -0
  175. package/dist/server/tool-definitions.js.map +1 -0
  176. package/dist/server/tool-input.d.ts +37 -0
  177. package/dist/server/tool-input.d.ts.map +1 -0
  178. package/dist/server/tool-input.js +211 -0
  179. package/dist/server/tool-input.js.map +1 -0
  180. package/dist/server/types.d.ts +307 -0
  181. package/dist/server/types.d.ts.map +1 -0
  182. package/dist/server/types.js +3 -0
  183. package/dist/server/types.js.map +1 -0
  184. package/dist/server-main.d.ts +40 -0
  185. package/dist/server-main.d.ts.map +1 -0
  186. package/dist/server-main.js +254 -0
  187. package/dist/server-main.js.map +1 -0
  188. package/dist/utils/base-dirs.d.ts +145 -0
  189. package/dist/utils/base-dirs.d.ts.map +1 -0
  190. package/dist/utils/base-dirs.js +344 -0
  191. package/dist/utils/base-dirs.js.map +1 -0
  192. package/dist/utils/errors.d.ts +32 -0
  193. package/dist/utils/errors.d.ts.map +1 -0
  194. package/dist/utils/errors.js +61 -0
  195. package/dist/utils/errors.js.map +1 -0
  196. package/dist/utils/limits.d.ts +26 -0
  197. package/dist/utils/limits.d.ts.map +1 -0
  198. package/dist/utils/limits.js +28 -0
  199. package/dist/utils/limits.js.map +1 -0
  200. package/dist/utils/list-sources.d.ts +38 -0
  201. package/dist/utils/list-sources.d.ts.map +1 -0
  202. package/dist/utils/list-sources.js +40 -0
  203. package/dist/utils/list-sources.js.map +1 -0
  204. package/dist/utils/raw-data-utils.d.ts +76 -0
  205. package/dist/utils/raw-data-utils.d.ts.map +1 -0
  206. package/dist/utils/raw-data-utils.js +202 -0
  207. package/dist/utils/raw-data-utils.js.map +1 -0
  208. package/dist/utils/scan.d.ts +114 -0
  209. package/dist/utils/scan.d.ts.map +1 -0
  210. package/dist/utils/scan.js +209 -0
  211. package/dist/utils/scan.js.map +1 -0
  212. package/dist/utils/scope-match.d.ts +38 -0
  213. package/dist/utils/scope-match.d.ts.map +1 -0
  214. package/dist/utils/scope-match.js +86 -0
  215. package/dist/utils/scope-match.js.map +1 -0
  216. package/dist/utils/sensitive-path.d.ts +9 -0
  217. package/dist/utils/sensitive-path.d.ts.map +1 -0
  218. package/dist/utils/sensitive-path.js +78 -0
  219. package/dist/utils/sensitive-path.js.map +1 -0
  220. package/dist/utils/sync-path-key.d.ts +14 -0
  221. package/dist/utils/sync-path-key.d.ts.map +1 -0
  222. package/dist/utils/sync-path-key.js +27 -0
  223. package/dist/utils/sync-path-key.js.map +1 -0
  224. package/dist/utils/type-guards.d.ts +18 -0
  225. package/dist/utils/type-guards.d.ts.map +1 -0
  226. package/dist/utils/type-guards.js +34 -0
  227. package/dist/utils/type-guards.js.map +1 -0
  228. package/dist/utils/visual-profile.d.ts +10 -0
  229. package/dist/utils/visual-profile.d.ts.map +1 -0
  230. package/dist/utils/visual-profile.js +15 -0
  231. package/dist/utils/visual-profile.js.map +1 -0
  232. package/dist/vectordb/index.d.ts +132 -0
  233. package/dist/vectordb/index.d.ts.map +1 -0
  234. package/dist/vectordb/index.js +617 -0
  235. package/dist/vectordb/index.js.map +1 -0
  236. package/dist/vectordb/search-filters.d.ts +15 -0
  237. package/dist/vectordb/search-filters.d.ts.map +1 -0
  238. package/dist/vectordb/search-filters.js +129 -0
  239. package/dist/vectordb/search-filters.js.map +1 -0
  240. package/dist/vectordb/types.d.ts +194 -0
  241. package/dist/vectordb/types.d.ts.map +1 -0
  242. package/dist/vectordb/types.js +237 -0
  243. package/dist/vectordb/types.js.map +1 -0
  244. package/package.json +108 -0
  245. package/skills/mcp-local-rag/SKILL.md +234 -0
  246. package/skills/mcp-local-rag/references/cli-reference.md +190 -0
  247. package/skills/mcp-local-rag/references/html-ingestion.md +78 -0
@@ -0,0 +1,429 @@
1
+ // Embedder implementation with Transformers.js
2
+ import { env, ModelRegistry, pipeline, } from '@huggingface/transformers';
3
+ import { AppError, toError } from '../utils/errors.js';
4
+ import { isObjectLike } from '../utils/type-guards.js';
5
+ /** True when the loaded pipeline exposes the call and tokenizer surface used here. */
6
+ function isEmbeddingPipeline(value) {
7
+ return (typeof value === 'function' && 'tokenizer' in value && typeof value.tokenizer === 'function');
8
+ }
9
+ // ============================================
10
+ // Token Limit Clamp
11
+ // ============================================
12
+ /** Above this a reported length is a sentinel, such as `bge-large-zh-v1.5`'s `1e30`. */
13
+ const MAX_PLAUSIBLE_TOKENS = 1e6;
14
+ /**
15
+ * Withheld on the window-only branch, where no tokenizer limit is trustworthy:
16
+ * the RoBERTa family's padding-index offset makes the usable window
17
+ * `max_position_embeddings - 2`.
18
+ */
19
+ const RESERVED_POSITIONS = 2;
20
+ /** A reported length usable as a limit, or `null` when it is absent or a sentinel. */
21
+ function usableTokenLimit(value) {
22
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
23
+ return null;
24
+ }
25
+ return value >= 1 && value <= MAX_PLAUSIBLE_TOKENS ? Math.floor(value) : null;
26
+ }
27
+ function readPositionWindow(candidate) {
28
+ return usableTokenLimit(candidate.model?.config?.max_position_embeddings);
29
+ }
30
+ function resolveEffectiveCap(positionWindow, tokenizerLimit) {
31
+ if (positionWindow === null) {
32
+ return tokenizerLimit;
33
+ }
34
+ if (tokenizerLimit !== null) {
35
+ return Math.min(positionWindow, tokenizerLimit);
36
+ }
37
+ // A window narrower than the reserve cannot yield a positive cap.
38
+ return Math.max(1, positionWindow - RESERVED_POSITIONS);
39
+ }
40
+ /**
41
+ * Bound the pipeline's tokenization length to the model's position window, by
42
+ * installing a proxy on `candidate`'s tokenizer.
43
+ *
44
+ * The pipeline tokenizes with no `max_length`, which resolves to
45
+ * `model_max_length ?? Infinity` and then to the batch's longest sequence, so a
46
+ * model whose `tokenizer_config.json` omits a real limit sends more positions
47
+ * than it has position embeddings and onnxruntime fails in the
48
+ * position-embedding `Add` node (#202).
49
+ *
50
+ * The measurement tokenizer is captured before the proxy, so measurement
51
+ * reports true lengths. A `Proxy` is used because `model_max_length` is a getter
52
+ * with no setter. An unrecognized shape, or no usable limit, leaves `candidate`
53
+ * untouched.
54
+ */
55
+ export function installTokenLimitClamp(candidate) {
56
+ if (!isEmbeddingPipeline(candidate)) {
57
+ return { tokenLimit: null, measurementTokenizer: null };
58
+ }
59
+ const measurementTokenizer = candidate.tokenizer;
60
+ const tokenizerLimit = usableTokenLimit(measurementTokenizer.model_max_length);
61
+ const tokenLimit = resolveEffectiveCap(readPositionWindow(candidate), tokenizerLimit);
62
+ if (tokenLimit === null) {
63
+ return { tokenLimit: null, measurementTokenizer };
64
+ }
65
+ candidate.tokenizer = new Proxy(measurementTokenizer, {
66
+ apply(target, thisArg, args) {
67
+ const [input, options] = args;
68
+ const clamped = {
69
+ ...(isObjectLike(options) ? options : {}),
70
+ max_length: tokenLimit,
71
+ truncation: true,
72
+ };
73
+ return Reflect.apply(target, thisArg, [input, clamped]);
74
+ },
75
+ });
76
+ return { tokenLimit, measurementTokenizer };
77
+ }
78
+ /** True when every entry exposes the numeric `length` the batching math reads. */
79
+ function isTokenLengthArray(value) {
80
+ return (Array.isArray(value) &&
81
+ value.every((entry) => typeof entry === 'object' &&
82
+ entry !== null &&
83
+ 'length' in entry &&
84
+ typeof entry.length === 'number'));
85
+ }
86
+ // Keep estimated padding waste below one-third of dense self-attention work.
87
+ const MAX_PADDING_AMPLIFICATION = 1.5;
88
+ function estimatePaddingAmplification(inputs) {
89
+ let maxTokenLength = 0;
90
+ let individualWork = 0;
91
+ for (const input of inputs) {
92
+ maxTokenLength = Math.max(maxTokenLength, input.tokenLength);
93
+ individualWork += input.tokenLength ** 2;
94
+ }
95
+ return (inputs.length * maxTokenLength ** 2) / individualWork;
96
+ }
97
+ function deferBatchOutliers(inputs) {
98
+ const batch = [...inputs];
99
+ const deferred = [];
100
+ while (batch.length > 1) {
101
+ if (estimatePaddingAmplification(batch) <= MAX_PADDING_AMPLIFICATION) {
102
+ break;
103
+ }
104
+ let longestIndex = 0;
105
+ let longestTokens = batch[0]?.tokenLength ?? 0;
106
+ for (let index = 1; index < batch.length; index++) {
107
+ const tokenLength = batch[index]?.tokenLength ?? 0;
108
+ if (tokenLength > longestTokens) {
109
+ longestIndex = index;
110
+ longestTokens = tokenLength;
111
+ }
112
+ }
113
+ const longest = batch[longestIndex];
114
+ if (longest === undefined) {
115
+ break;
116
+ }
117
+ deferred.push(longest);
118
+ batch.splice(longestIndex, 1);
119
+ }
120
+ return { batch, deferred };
121
+ }
122
+ // ============================================
123
+ // Error Classes
124
+ // ============================================
125
+ /**
126
+ * Embedding generation error
127
+ */
128
+ export class EmbeddingError extends AppError {
129
+ constructor(message, options) {
130
+ super(message, 'embedder', 'internal', options);
131
+ this.name = 'EmbeddingError';
132
+ }
133
+ }
134
+ // ============================================
135
+ // Embedder Class
136
+ // ============================================
137
+ /** Transformers.js wrapper: lazily loaded model, batched embedding. */
138
+ export class Embedder {
139
+ // Using unknown to avoid TS2590 (union type too complex with @types/jsdom)
140
+ model = null;
141
+ initPromise = null;
142
+ /** The resolved cap, or `null` before initialization and in degraded mode. */
143
+ tokenLimit = null;
144
+ /** The pre-clamp tokenizer, so measurement never reports clamped lengths. */
145
+ measurementTokenizer = null;
146
+ /**
147
+ * One-shot flags, per instance: each state belongs to this embedder's model.
148
+ * They survive `dispose()`; re-initialization is not new information.
149
+ */
150
+ truncationWarned = false;
151
+ degradedModeWarned = false;
152
+ config;
153
+ constructor(config) {
154
+ this.config = config;
155
+ }
156
+ /**
157
+ * Release resources held by the Embedder pipeline
158
+ */
159
+ async dispose() {
160
+ const model = this.model;
161
+ const dispose = isObjectLike(model) ? model['dispose'] : undefined;
162
+ if (typeof dispose === 'function') {
163
+ try {
164
+ await dispose.call(model);
165
+ }
166
+ catch (error) {
167
+ console.error('Error disposing embedder model:', error);
168
+ }
169
+ }
170
+ this.model = null;
171
+ this.initPromise = null;
172
+ this.tokenLimit = null;
173
+ this.measurementTokenizer = null;
174
+ }
175
+ /**
176
+ * Initialize Transformers.js model
177
+ */
178
+ async initialize() {
179
+ // Skip if already initialized
180
+ if (this.model) {
181
+ return;
182
+ }
183
+ // Set cache directory BEFORE creating pipeline
184
+ env.cacheDir = this.config.cacheDir;
185
+ if (process.env['HF_ENDPOINT']) {
186
+ env.remoteHost = process.env['HF_ENDPOINT'];
187
+ }
188
+ // No fallback — if the requested device fails, init throws.
189
+ const device = this.config.device || 'cpu';
190
+ console.error(`Embedder: Setting cache directory to "${this.config.cacheDir}"`);
191
+ console.error(`Embedder: Loading model "${this.config.modelPath}" on device "${device}"...`);
192
+ try {
193
+ this.model = await pipeline('feature-extraction', this.config.modelPath, {
194
+ // The sole fp32 default literal. Both values pass through
195
+ // un-allowlisted (see `resolveDevice`) into a closed literal union.
196
+ // biome-ignore lint/nursery/noUnsafeTypeAssertion: un-allowlisted passthrough to a closed literal union
197
+ dtype: (this.config.dtype ?? 'fp32'),
198
+ // biome-ignore lint/nursery/noUnsafeTypeAssertion: un-allowlisted passthrough to a closed literal union
199
+ device: device,
200
+ });
201
+ const clamp = installTokenLimitClamp(this.model);
202
+ this.tokenLimit = clamp.tokenLimit;
203
+ this.measurementTokenizer = clamp.measurementTokenizer;
204
+ console.error(`Embedder: Model loaded successfully (device=${device})`);
205
+ }
206
+ catch (error) {
207
+ const nativeError = toError(error);
208
+ // Only enrich when RAG_DTYPE was explicitly set (unset is `undefined` per
209
+ // TD-5). Enrichment never runs on the happy path and never on the unset
210
+ // path, so normal operation adds zero network. Always re-throw — an
211
+ // unavailable dtype fails loud, never silently downgrades (TD-2).
212
+ const message = await this.enrichDtypeFailureMessage(nativeError.message);
213
+ throw new EmbeddingError(message, { cause: nativeError });
214
+ }
215
+ }
216
+ /**
217
+ * Best-effort failure-path enrichment for an explicit `RAG_DTYPE`: name the
218
+ * dtypes the model does provide when the requested one is absent.
219
+ *
220
+ * The enumeration is a Hub network call in its own try/catch, so an
221
+ * air-gapped run degrades to a generic dtype-aware message instead of
222
+ * surfacing a confusing secondary error. Never throws, and never converts
223
+ * the load failure into a fallback — the caller always re-throws.
224
+ */
225
+ async enrichDtypeFailureMessage(nativeMessage) {
226
+ const requestedDtype = this.config.dtype;
227
+ if (requestedDtype === undefined) {
228
+ return nativeMessage;
229
+ }
230
+ try {
231
+ const availableDtypes = await ModelRegistry.get_available_dtypes(this.config.modelPath);
232
+ if (availableDtypes.includes(requestedDtype)) {
233
+ // The requested dtype exists for this model, so the load failed for some
234
+ // other reason — keep the native message, don't misattribute it to dtype.
235
+ return nativeMessage;
236
+ }
237
+ return `Model "${this.config.modelPath}" provides dtypes [${availableDtypes.join(', ')}]; requested dtype "${requestedDtype}" is unavailable. Set RAG_DTYPE to one of the available dtypes, or leave it unset for the fp32 default.`;
238
+ }
239
+ catch {
240
+ // Enumeration unavailable (e.g. offline). Degrade to a generic clear,
241
+ // dtype-aware message — no secondary error, still re-thrown by the caller.
242
+ return `Failed to load model "${this.config.modelPath}" with requested dtype "${requestedDtype}". The model may not provide this dtype, and the available-dtype list could not be retrieved. Set RAG_DTYPE to a dtype the model provides, or leave it unset for the fp32 default. (${nativeMessage})`;
243
+ }
244
+ }
245
+ /**
246
+ * Ensure model is initialized (lazy initialization)
247
+ * This method is called automatically by embed() and embedBatch()
248
+ */
249
+ async ensureInitialized() {
250
+ // Already initialized
251
+ if (this.model) {
252
+ return;
253
+ }
254
+ // Initialization already in progress, wait for it
255
+ if (this.initPromise !== null) {
256
+ await this.initPromise;
257
+ return;
258
+ }
259
+ console.error('Embedder: First use detected. Initializing model (downloading ~90MB, may take 1-2 minutes)...');
260
+ this.initPromise = this.initialize().catch((error) => {
261
+ // Clear initPromise on failure to allow retry on the next call.
262
+ this.initPromise = null;
263
+ throw error;
264
+ });
265
+ await this.initPromise;
266
+ }
267
+ /**
268
+ * The effective token cap, or `null` when none could be resolved.
269
+ *
270
+ * Self-initializing: the value exists only after the model loads, and a
271
+ * caller may need it before the first embedding.
272
+ */
273
+ async getTokenLimit() {
274
+ await this.ensureInitialized();
275
+ if (this.tokenLimit === null) {
276
+ this.warnDegradedMode();
277
+ }
278
+ return this.tokenLimit;
279
+ }
280
+ /**
281
+ * Report once that no cap was resolved. Warning here rather than in
282
+ * `initialize()` covers every consumer, which all read the cap through
283
+ * {@link getTokenLimit}.
284
+ */
285
+ warnDegradedMode() {
286
+ if (this.degradedModeWarned) {
287
+ return;
288
+ }
289
+ this.degradedModeWarned = true;
290
+ console.error(`Embedder: no position-window token limit could be resolved for model "${this.config.modelPath}". Inputs are not length-guarded and oversized input may fail at inference.`);
291
+ }
292
+ /**
293
+ * The lengths batch planning runs on: `min(trueLength, cap)`, the length the
294
+ * clamped pipeline actually feeds the model. Warns once when a true length
295
+ * exceeds the cap.
296
+ */
297
+ async planTokenLengths(texts) {
298
+ const tokenLimit = await this.getTokenLimit();
299
+ const trueLengths = await this.countTokens(texts);
300
+ if (tokenLimit === null) {
301
+ return trueLengths;
302
+ }
303
+ let longestObserved = 0;
304
+ for (const length of trueLengths) {
305
+ longestObserved = Math.max(longestObserved, length);
306
+ }
307
+ if (longestObserved > tokenLimit && !this.truncationWarned) {
308
+ this.truncationWarned = true;
309
+ console.error(`Embedder: input exceeds the model token limit of ${tokenLimit} tokens (longest input measured ${longestObserved} tokens). Text past the limit is truncated before embedding.`);
310
+ }
311
+ return trueLengths.map((length) => Math.min(length, tokenLimit));
312
+ }
313
+ /**
314
+ * The true token length of each text, in input order. Tokenization only, no
315
+ * inference.
316
+ *
317
+ * Measured with `truncation: false` through the pre-clamp tokenizer, so a
318
+ * length above {@link getTokenLimit} means inference will truncate. Throws
319
+ * when no such tokenizer was captured, rather than returning a length
320
+ * measured through an unknown surface.
321
+ */
322
+ async countTokens(texts) {
323
+ if (texts.length === 0) {
324
+ return [];
325
+ }
326
+ await this.ensureInitialized();
327
+ const tokenizer = this.measurementTokenizer;
328
+ if (tokenizer === null) {
329
+ throw new EmbeddingError('Embedder tokenizer is unavailable for measurement');
330
+ }
331
+ const tokenized = tokenizer(texts, { padding: false, truncation: false, return_tensor: false });
332
+ const inputIds = tokenized?.input_ids;
333
+ if (!isTokenLengthArray(inputIds) || inputIds.length !== texts.length) {
334
+ throw new EmbeddingError('Unexpected embedder tokenizer output shape');
335
+ }
336
+ return inputIds.map((ids) => ids.length);
337
+ }
338
+ /**
339
+ * Single-text embedding; the vector dimension depends on the model.
340
+ *
341
+ * Delegates to {@link embedBatch} so this path shares its clamp, measurement
342
+ * and warning rather than reaching the pipeline unguarded.
343
+ */
344
+ async embed(text) {
345
+ const embeddings = await this.embedBatch([text]);
346
+ const embedding = embeddings[0];
347
+ if (embedding === undefined) {
348
+ throw new EmbeddingError('Missing embedder batch output row');
349
+ }
350
+ return embedding;
351
+ }
352
+ /** Batched embedding; the vector dimension depends on the model. */
353
+ async embedBatch(texts) {
354
+ // Nothing to embed → skip model init entirely.
355
+ if (texts.length === 0) {
356
+ return [];
357
+ }
358
+ if (texts.some((text) => text.length === 0)) {
359
+ throw new EmbeddingError('Cannot generate embedding for empty text');
360
+ }
361
+ // Lazy initialization: initialize on first use if not already initialized
362
+ await this.ensureInitialized();
363
+ try {
364
+ const options = { pooling: 'mean', normalize: true };
365
+ // True batched inference: the pipeline takes an array and returns one
366
+ // [batchLen, dim] tensor per forward pass. Calling it once per text via
367
+ // Promise.all made `batchSize` meaningless, since onnxruntime inference
368
+ // is not parallelized that way. Mean-pooling honors the attention mask,
369
+ // so per-row vectors match the single-text result.
370
+ if (!isEmbeddingPipeline(this.model)) {
371
+ throw new EmbeddingError('Embedder pipeline is not callable');
372
+ }
373
+ const modelCall = this.model;
374
+ // One measurement per call, so planning and truncation reporting cannot
375
+ // disagree about a length.
376
+ const plannedLengths = await this.planTokenLengths(texts);
377
+ const embeddings = Array.from({ length: texts.length });
378
+ const deferred = [];
379
+ const embedInputs = async (inputs) => {
380
+ const output = await modelCall(inputs.map((input) => input.text), options);
381
+ // Validate the output shape before slicing so a runtime/model contract
382
+ // change surfaces as a clear error rather than silently wrong vectors.
383
+ const dims = output?.dims;
384
+ const dim = Array.isArray(dims) ? dims[dims.length - 1] : undefined;
385
+ const data = output?.data;
386
+ if (!(data instanceof Float32Array) ||
387
+ typeof dim !== 'number' ||
388
+ dim <= 0 ||
389
+ data.length !== inputs.length * dim) {
390
+ throw new EmbeddingError('Unexpected embedder batch output shape');
391
+ }
392
+ for (const [row, input] of inputs.entries()) {
393
+ embeddings[input.originalIndex] = Array.from(data.subarray(row * dim, (row + 1) * dim));
394
+ }
395
+ };
396
+ for (let i = 0; i < texts.length; i += this.config.batchSize) {
397
+ const batchTexts = texts.slice(i, i + this.config.batchSize);
398
+ const indexedInputs = batchTexts.map((text, batchIndex) => {
399
+ const originalIndex = i + batchIndex;
400
+ const tokenLength = plannedLengths[originalIndex];
401
+ if (tokenLength === undefined) {
402
+ throw new EmbeddingError('Unexpected embedder tokenizer output shape');
403
+ }
404
+ return { text, originalIndex, tokenLength };
405
+ });
406
+ const selected = deferBatchOutliers(indexedInputs);
407
+ deferred.push(...selected.deferred);
408
+ await embedInputs(selected.batch);
409
+ }
410
+ for (const input of deferred) {
411
+ await embedInputs([input]);
412
+ }
413
+ const complete = embeddings.filter((embedding) => embedding !== undefined);
414
+ if (complete.length !== embeddings.length) {
415
+ throw new EmbeddingError('Missing embedder batch output row');
416
+ }
417
+ return complete;
418
+ }
419
+ catch (error) {
420
+ if (error instanceof EmbeddingError) {
421
+ throw error;
422
+ }
423
+ throw new EmbeddingError(`Failed to generate batch embeddings: ${toError(error).message}`, {
424
+ cause: toError(error),
425
+ });
426
+ }
427
+ }
428
+ }
429
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/embedder/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { AppError } from '../utils/errors.js';
2
+ /** Remote embedding generation error. */
3
+ export declare class RemoteEmbeddingError extends AppError {
4
+ constructor(message: string, options?: {
5
+ cause?: Error;
6
+ });
7
+ }
8
+ /** Server responded with a retryable failure (429 / 5xx). */
9
+ export declare class RemoteEmbeddingRetryableError extends RemoteEmbeddingError {
10
+ readonly status: number;
11
+ constructor(status: number, body: string, serverUrl: string);
12
+ }
13
+ export interface RemoteEmbedderConfig {
14
+ /** Base URL without trailing slash, e.g. http://gpu-host:8081 */
15
+ serverUrl: string;
16
+ /** Texts per POST (default 16, mirroring the local Embedder) */
17
+ batchSize: number;
18
+ /** Per-attempt HTTP timeout in ms (default 30_000) */
19
+ timeoutMs?: number;
20
+ }
21
+ /**
22
+ * Structural counterpart of the local `Embedder`: same public surface
23
+ * (`initialize / embed / embedBatch / dispose / tokenLimit`), with embedding
24
+ * compute delegated to a self-hosted server.
25
+ *
26
+ * Semantics intentionally aligned with the local class:
27
+ * - `tokenLimit` is always `null` — the remote server owns truncation, which
28
+ * maps to the local class's "degraded mode" (no cap, no clamp).
29
+ * - `dispose()` is a no-op — no in-process model resources.
30
+ * - `device` / `dtype` / `cacheDir` / `modelPath` are server-side concerns.
31
+ */
32
+ export declare class RemoteEmbedder {
33
+ private readonly config;
34
+ private dims;
35
+ private initialized;
36
+ constructor(config: RemoteEmbedderConfig);
37
+ /**
38
+ * Probe the server and record the embedding dimension so later responses
39
+ * can be validated (a dimension change means the server swapped models —
40
+ * fail fast instead of writing mixed-dimension vectors).
41
+ */
42
+ initialize(): Promise<void>;
43
+ dispose(): Promise<void>;
44
+ /** Remote servers decide their own truncation: no local cap, no clamp. */
45
+ get tokenLimit(): null;
46
+ embed(text: string): Promise<number[]>;
47
+ embedBatch(texts: string[]): Promise<number[][]>;
48
+ private validate;
49
+ private postEmbed;
50
+ }
51
+ //# sourceMappingURL=remote.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../src/embedder/remote.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAE7C,yCAAyC;AACzC,qBAAa,oBAAqB,SAAQ,QAAQ;IAChD,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,EAGvD;CACF;AAED,6DAA6D;AAC7D,qBAAa,6BAA8B,SAAQ,oBAAoB;IACrE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IAEvB,YAAY,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAM1D;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAA;IACjB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAA;IACjB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAwED;;;;;;;;;;GAUG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,IAAI,CAAsB;IAClC,OAAO,CAAC,WAAW,CAAiB;IAEpC,YAAY,MAAM,EAAE,oBAAoB,EAEvC;IAED;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAehC;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAG7B;IAED,0EAA0E;IAC1E,IAAI,UAAU,IAAI,IAAI,CAErB;IAEK,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAS3C;IAEK,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAUrD;IAED,OAAO,CAAC,QAAQ;YAoBF,SAAS;CAqBxB"}