@reftrixmcp/ml 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 (97) hide show
  1. package/LICENSE +661 -0
  2. package/dist/dinov2/index.d.ts +7 -0
  3. package/dist/dinov2/index.d.ts.map +1 -0
  4. package/dist/dinov2/index.js +7 -0
  5. package/dist/dinov2/index.js.map +1 -0
  6. package/dist/dinov2/service.d.ts +106 -0
  7. package/dist/dinov2/service.d.ts.map +1 -0
  8. package/dist/dinov2/service.js +446 -0
  9. package/dist/dinov2/service.js.map +1 -0
  10. package/dist/dinov2/worker-thread-types.d.ts +77 -0
  11. package/dist/dinov2/worker-thread-types.d.ts.map +1 -0
  12. package/dist/dinov2/worker-thread-types.js +4 -0
  13. package/dist/dinov2/worker-thread-types.js.map +1 -0
  14. package/dist/dinov2/worker-thread.d.ts +2 -0
  15. package/dist/dinov2/worker-thread.d.ts.map +1 -0
  16. package/dist/dinov2/worker-thread.js +231 -0
  17. package/dist/dinov2/worker-thread.js.map +1 -0
  18. package/dist/embeddings/index.d.ts +12 -0
  19. package/dist/embeddings/index.d.ts.map +1 -0
  20. package/dist/embeddings/index.js +13 -0
  21. package/dist/embeddings/index.js.map +1 -0
  22. package/dist/embeddings/multimodal-embedding.service.d.ts +400 -0
  23. package/dist/embeddings/multimodal-embedding.service.d.ts.map +1 -0
  24. package/dist/embeddings/multimodal-embedding.service.js +650 -0
  25. package/dist/embeddings/multimodal-embedding.service.js.map +1 -0
  26. package/dist/embeddings/service.d.ts +261 -0
  27. package/dist/embeddings/service.d.ts.map +1 -0
  28. package/dist/embeddings/service.js +1093 -0
  29. package/dist/embeddings/service.js.map +1 -0
  30. package/dist/embeddings/style-embedding.service.d.ts +117 -0
  31. package/dist/embeddings/style-embedding.service.d.ts.map +1 -0
  32. package/dist/embeddings/style-embedding.service.js +157 -0
  33. package/dist/embeddings/style-embedding.service.js.map +1 -0
  34. package/dist/embeddings/types.d.ts +83 -0
  35. package/dist/embeddings/types.d.ts.map +1 -0
  36. package/dist/embeddings/types.js +4 -0
  37. package/dist/embeddings/types.js.map +1 -0
  38. package/dist/embeddings/vision-embedding.service.d.ts +70 -0
  39. package/dist/embeddings/vision-embedding.service.d.ts.map +1 -0
  40. package/dist/embeddings/vision-embedding.service.js +221 -0
  41. package/dist/embeddings/vision-embedding.service.js.map +1 -0
  42. package/dist/embeddings/vision-embedding.types.d.ts +102 -0
  43. package/dist/embeddings/vision-embedding.types.d.ts.map +1 -0
  44. package/dist/embeddings/vision-embedding.types.js +4 -0
  45. package/dist/embeddings/vision-embedding.types.js.map +1 -0
  46. package/dist/embeddings/worker-thread-types.d.ts +152 -0
  47. package/dist/embeddings/worker-thread-types.d.ts.map +1 -0
  48. package/dist/embeddings/worker-thread-types.js +4 -0
  49. package/dist/embeddings/worker-thread-types.js.map +1 -0
  50. package/dist/embeddings/worker-thread.d.ts +4 -0
  51. package/dist/embeddings/worker-thread.d.ts.map +1 -0
  52. package/dist/embeddings/worker-thread.js +441 -0
  53. package/dist/embeddings/worker-thread.js.map +1 -0
  54. package/dist/index.d.ts +18 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +19 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/search/fulltext-helpers.d.ts +30 -0
  59. package/dist/search/fulltext-helpers.d.ts.map +1 -0
  60. package/dist/search/fulltext-helpers.js +40 -0
  61. package/dist/search/fulltext-helpers.js.map +1 -0
  62. package/dist/search/hybrid.d.ts +40 -0
  63. package/dist/search/hybrid.d.ts.map +1 -0
  64. package/dist/search/hybrid.js +61 -0
  65. package/dist/search/hybrid.js.map +1 -0
  66. package/dist/search/index.d.ts +12 -0
  67. package/dist/search/index.d.ts.map +1 -0
  68. package/dist/search/index.js +11 -0
  69. package/dist/search/index.js.map +1 -0
  70. package/dist/search/rrf.d.ts +69 -0
  71. package/dist/search/rrf.d.ts.map +1 -0
  72. package/dist/search/rrf.js +108 -0
  73. package/dist/search/rrf.js.map +1 -0
  74. package/dist/search/types.d.ts +130 -0
  75. package/dist/search/types.d.ts.map +1 -0
  76. package/dist/search/types.js +4 -0
  77. package/dist/search/types.js.map +1 -0
  78. package/package.json +65 -0
  79. package/src/dinov2/index.ts +21 -0
  80. package/src/dinov2/service.ts +539 -0
  81. package/src/dinov2/worker-thread-types.ts +103 -0
  82. package/src/dinov2/worker-thread.ts +306 -0
  83. package/src/embeddings/index.ts +74 -0
  84. package/src/embeddings/multimodal-embedding.service.ts +992 -0
  85. package/src/embeddings/service.ts +1287 -0
  86. package/src/embeddings/style-embedding.service.ts +201 -0
  87. package/src/embeddings/types.ts +95 -0
  88. package/src/embeddings/vision-embedding.service.ts +273 -0
  89. package/src/embeddings/vision-embedding.types.ts +117 -0
  90. package/src/embeddings/worker-thread-types.ts +194 -0
  91. package/src/embeddings/worker-thread.ts +529 -0
  92. package/src/index.ts +70 -0
  93. package/src/search/fulltext-helpers.ts +45 -0
  94. package/src/search/hybrid.ts +107 -0
  95. package/src/search/index.ts +25 -0
  96. package/src/search/rrf.ts +154 -0
  97. package/src/search/types.ts +141 -0
@@ -0,0 +1,441 @@
1
+ // SPDX-FileCopyrightText: 2026 TKMD and Reftrix Contributors
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * ONNX Embedding Worker Thread
5
+ *
6
+ * Runs ONNX inference in a separate thread so CPU-bound inference
7
+ * does not block the main thread's event loop. This allows BullMQ
8
+ * heartbeats, IPC messages, and other async operations to proceed
9
+ * while inference is in progress.
10
+ *
11
+ * Architecture:
12
+ * - Main thread sends prefixed texts via parentPort messages.
13
+ * - This worker owns the entire ONNX pipeline lifecycle
14
+ * (init, inference, recycle, dispose).
15
+ * - Results are sent back as plain number[][] (structured clone safe).
16
+ * - ONNX Session/Tensor objects never cross thread boundaries.
17
+ *
18
+ * @module embeddings/worker-thread
19
+ */
20
+ import { parentPort } from "node:worker_threads";
21
+ import { createRequire } from "node:module";
22
+ import fs from "node:fs";
23
+ import nodePath from "node:path";
24
+ /**
25
+ * Detect the ONNX execution provider based on environment configuration.
26
+ *
27
+ * Checks ONNX_EXECUTION_PROVIDER env var and verifies that the CUDA
28
+ * provider shared library is available on disk. Falls back to CPU
29
+ * gracefully if the provider is not installed.
30
+ */
31
+ function detectExecutionProvider() {
32
+ const envProvider = process.env.ONNX_EXECUTION_PROVIDER;
33
+ if (envProvider === "cuda" || envProvider === "rocm") {
34
+ const cudaAvailable = verifyCudaAvailability();
35
+ if (cudaAvailable) {
36
+ return "cuda";
37
+ }
38
+ console.warn("[EmbeddingWorker] ONNX_EXECUTION_PROVIDER=%s but CUDA provider not available, falling back to CPU", envProvider);
39
+ return "cpu";
40
+ }
41
+ return "cpu";
42
+ }
43
+ /**
44
+ * Verify that CUDA provider (libonnxruntime_providers_cuda.so) is available.
45
+ *
46
+ * onnxruntime-node can download the CUDA provider shared library via
47
+ * `ONNXRUNTIME_NODE_INSTALL_CUDA=v12 node .../install.js`. This function
48
+ * checks for its presence on disk rather than trying to resolve a
49
+ * non-existent npm package (onnxruntime-gpu is Python-only).
50
+ */
51
+ function verifyCudaAvailability() {
52
+ try {
53
+ const esmRequire = createRequire(import.meta.url);
54
+ const ortNodePath = esmRequire.resolve("onnxruntime-node");
55
+ // require.resolve returns e.g. .../onnxruntime-node/dist/index.js
56
+ // Walk up to package root by finding the directory containing package.json
57
+ let packageDir = nodePath.dirname(ortNodePath);
58
+ for (let i = 0; i < 5; i++) {
59
+ if (fs.existsSync(nodePath.join(packageDir, "package.json")))
60
+ break;
61
+ packageDir = nodePath.dirname(packageDir);
62
+ }
63
+ // Search across napi versions (v3, v6, etc.) for CUDA provider
64
+ const binDir = nodePath.join(packageDir, "bin");
65
+ if (fs.existsSync(binDir)) {
66
+ const napiDirs = fs.readdirSync(binDir).filter((d) => d.startsWith("napi-v"));
67
+ for (const napiDir of napiDirs) {
68
+ const cudaProviderPath = nodePath.join(binDir, napiDir, "linux", "x64", "libonnxruntime_providers_cuda.so");
69
+ if (fs.existsSync(cudaProviderPath)) {
70
+ return true;
71
+ }
72
+ }
73
+ }
74
+ console.warn("[EmbeddingWorker] CUDA provider not found in: %s", binDir);
75
+ return false;
76
+ }
77
+ catch {
78
+ console.warn("[EmbeddingWorker] Cannot verify CUDA provider: onnxruntime-node not found");
79
+ return false;
80
+ }
81
+ }
82
+ // =====================================================
83
+ // Worker state
84
+ // =====================================================
85
+ let pipeline = null;
86
+ let initPromise = null;
87
+ let inferencesSinceRecycle = 0;
88
+ let totalRecycles = 0;
89
+ let resolvedProvider = "cpu";
90
+ /** Whether resolvedProvider was explicitly set by a switch-provider message. */
91
+ let providerExplicitlySet = false;
92
+ let config = {
93
+ modelId: "Xenova/multilingual-e5-base",
94
+ cacheDir: "./.cache/models",
95
+ device: "cpu",
96
+ dtype: "fp32",
97
+ pipelineRecycleThreshold: 30,
98
+ };
99
+ const EMBEDDING_DIMENSION = 768;
100
+ // =====================================================
101
+ // Pipeline management
102
+ // =====================================================
103
+ function normalizeVector(vector) {
104
+ const norm = Math.sqrt(vector.reduce((sum, val) => sum + val * val, 0));
105
+ if (norm === 0)
106
+ return vector;
107
+ return vector.map((val) => val / norm);
108
+ }
109
+ /**
110
+ * Verify that LD_LIBRARY_PATH is set at the OS level (not just process.env).
111
+ *
112
+ * dlopen() reads LD_LIBRARY_PATH from the kernel environment (/proc/self/environ),
113
+ * NOT from process.env modifications made at runtime. If LD_LIBRARY_PATH was set
114
+ * after process startup (e.g. by loadEnvLocal()), dlopen() cannot find CUDA
115
+ * libraries and ONNX Runtime CUDA provider initialization will segfault or throw.
116
+ *
117
+ * Returns true only if LD_LIBRARY_PATH was present in the original process environment.
118
+ */
119
+ function isLdLibraryPathSetAtOsLevel() {
120
+ try {
121
+ const procEnv = fs.readFileSync("/proc/self/environ", "utf-8");
122
+ return procEnv.includes("LD_LIBRARY_PATH");
123
+ }
124
+ catch {
125
+ // /proc/self/environ not available (non-Linux) — assume set
126
+ return true;
127
+ }
128
+ }
129
+ async function initializePipeline() {
130
+ if (pipeline)
131
+ return;
132
+ if (initPromise)
133
+ return initPromise;
134
+ initPromise = (async () => {
135
+ try {
136
+ // Only auto-detect from env on first init. If provider was explicitly
137
+ // set by a switch-provider message, respect that setting.
138
+ if (!providerExplicitlySet) {
139
+ resolvedProvider = detectExecutionProvider();
140
+ }
141
+ // Safety check: if CUDA is requested but LD_LIBRARY_PATH was not set at
142
+ // the OS level (only set via loadEnvLocal at runtime), CUDA init will crash
143
+ // because dlopen() can't find CUDA shared libraries. Fall back to CPU.
144
+ if (resolvedProvider === "cuda" && !isLdLibraryPathSetAtOsLevel()) {
145
+ console.warn("[EmbeddingWorker] CUDA requested but LD_LIBRARY_PATH not set at OS level. " +
146
+ "dlopen() cannot find CUDA libraries. Falling back to CPU. " +
147
+ "To use CUDA, set LD_LIBRARY_PATH before starting the Node.js process.");
148
+ resolvedProvider = "cpu";
149
+ }
150
+ const effectiveDevice = resolvedProvider === "cuda" ? "cuda" : config.device;
151
+ // eslint-disable-next-line no-console
152
+ console.log("[EmbeddingWorker] Initializing ONNX pipeline", {
153
+ model: config.modelId,
154
+ requestedDevice: config.device,
155
+ resolvedProvider,
156
+ effectiveDevice,
157
+ dtype: config.dtype,
158
+ recycleThreshold: config.pipelineRecycleThreshold,
159
+ });
160
+ const { pipeline: createPipeline } = await import("@huggingface/transformers");
161
+ // Attempt to create pipeline with the resolved device.
162
+ // If CUDA init fails (e.g. library not found), catch and retry with CPU.
163
+ try {
164
+ pipeline = (await createPipeline("feature-extraction", config.modelId, {
165
+ dtype: config.dtype,
166
+ device: effectiveDevice,
167
+ }));
168
+ }
169
+ catch (deviceError) {
170
+ if (effectiveDevice !== "cpu") {
171
+ // CUDA/GPU init failed — fallback to CPU
172
+ const deviceErrorMsg = deviceError instanceof Error ? deviceError.message : String(deviceError);
173
+ console.warn("[EmbeddingWorker] %s pipeline creation failed, falling back to CPU: %s", effectiveDevice, deviceErrorMsg);
174
+ resolvedProvider = "cpu";
175
+ pipeline = (await createPipeline("feature-extraction", config.modelId, {
176
+ dtype: config.dtype,
177
+ device: "cpu",
178
+ }));
179
+ }
180
+ else {
181
+ throw deviceError;
182
+ }
183
+ }
184
+ // eslint-disable-next-line no-console
185
+ console.log("[EmbeddingWorker] ONNX pipeline ready (provider: %s)", resolvedProvider);
186
+ }
187
+ catch (error) {
188
+ initPromise = null;
189
+ const message = error instanceof Error ? error.message : "Unknown error";
190
+ throw new Error(`Failed to load embedding model in worker thread: ${message}`);
191
+ }
192
+ })();
193
+ return initPromise;
194
+ }
195
+ async function disposePipeline() {
196
+ if (pipeline && typeof pipeline.dispose === "function") {
197
+ try {
198
+ await pipeline.dispose();
199
+ }
200
+ catch {
201
+ // Disposal failure should not break the workflow
202
+ }
203
+ }
204
+ pipeline = null;
205
+ initPromise = null;
206
+ inferencesSinceRecycle = 0;
207
+ }
208
+ async function recyclePipelineIfNeeded(inferenceCount) {
209
+ inferencesSinceRecycle += inferenceCount;
210
+ const threshold = config.pipelineRecycleThreshold;
211
+ if (threshold <= 0)
212
+ return;
213
+ if (inferencesSinceRecycle >= threshold) {
214
+ await disposePipeline();
215
+ totalRecycles++;
216
+ if (typeof global.gc === "function") {
217
+ global.gc();
218
+ }
219
+ }
220
+ }
221
+ // =====================================================
222
+ // Inference functions
223
+ // =====================================================
224
+ /**
225
+ * Extract number[] from a pipeline output, disposing the tensor.
226
+ */
227
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
228
+ function extractSingleEmbedding(output) {
229
+ let embedding;
230
+ if (output && typeof output.tolist === "function") {
231
+ const result = output.tolist();
232
+ embedding = Array.isArray(result[0]) ? result[0] : result;
233
+ if (typeof output.dispose === "function") {
234
+ output.dispose();
235
+ }
236
+ }
237
+ else if (Array.isArray(output)) {
238
+ embedding = output;
239
+ }
240
+ else {
241
+ throw new Error("Unexpected embedding output format");
242
+ }
243
+ if (embedding.length !== EMBEDDING_DIMENSION) {
244
+ // Non-fatal: warn but continue
245
+ }
246
+ return normalizeVector(embedding);
247
+ }
248
+ /**
249
+ * Extract number[][] from a batch pipeline output, disposing the tensor.
250
+ */
251
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
252
+ function extractBatchEmbeddings(output) {
253
+ let batchEmbeddings;
254
+ if (output && typeof output.tolist === "function") {
255
+ batchEmbeddings = output.tolist();
256
+ if (typeof output.dispose === "function") {
257
+ output.dispose();
258
+ }
259
+ }
260
+ else if (Array.isArray(output)) {
261
+ batchEmbeddings = output;
262
+ }
263
+ else {
264
+ throw new Error("Unexpected batch embedding output format");
265
+ }
266
+ return batchEmbeddings.map(normalizeVector);
267
+ }
268
+ async function generateSingle(text) {
269
+ await initializePipeline();
270
+ if (!pipeline)
271
+ throw new Error("Pipeline not initialized");
272
+ const output = await pipeline(text, { pooling: "mean", normalize: true });
273
+ const embedding = extractSingleEmbedding(output);
274
+ await recyclePipelineIfNeeded(1);
275
+ return embedding;
276
+ }
277
+ async function generateBatch(texts) {
278
+ if (texts.length === 0)
279
+ return [];
280
+ const BATCH_SIZE = 32;
281
+ const allEmbeddings = [];
282
+ for (let batchStart = 0; batchStart < texts.length; batchStart += BATCH_SIZE) {
283
+ const batchEnd = Math.min(batchStart + BATCH_SIZE, texts.length);
284
+ const batch = texts.slice(batchStart, batchEnd);
285
+ // Re-initialize if recycled during previous batch
286
+ await initializePipeline();
287
+ if (!pipeline)
288
+ throw new Error("Pipeline not initialized after recycle");
289
+ const output = await pipeline(batch, { pooling: "mean", normalize: true });
290
+ const batchEmbeddings = extractBatchEmbeddings(output);
291
+ allEmbeddings.push(...batchEmbeddings);
292
+ await recyclePipelineIfNeeded(batch.length);
293
+ }
294
+ return allEmbeddings;
295
+ }
296
+ // =====================================================
297
+ // Message handler
298
+ // =====================================================
299
+ function sendResponse(response) {
300
+ parentPort?.postMessage(response);
301
+ }
302
+ function sendError(requestId, originalType, error) {
303
+ const errorMessage = error instanceof Error ? error.message : String(error);
304
+ const response = {
305
+ type: "error",
306
+ requestId,
307
+ success: false,
308
+ error: errorMessage,
309
+ originalType,
310
+ };
311
+ parentPort?.postMessage(response);
312
+ }
313
+ async function handleMessage(message) {
314
+ switch (message.type) {
315
+ case "init": {
316
+ config = { ...config, ...message.config };
317
+ const startTime = Date.now();
318
+ await initializePipeline();
319
+ sendResponse({
320
+ type: "init",
321
+ requestId: message.requestId,
322
+ success: true,
323
+ loadTimeMs: Date.now() - startTime,
324
+ executionProvider: resolvedProvider,
325
+ });
326
+ break;
327
+ }
328
+ case "generate": {
329
+ const startTime = Date.now();
330
+ const embedding = await generateSingle(message.text);
331
+ sendResponse({
332
+ type: "generate",
333
+ requestId: message.requestId,
334
+ success: true,
335
+ embedding,
336
+ inferenceTimeMs: Date.now() - startTime,
337
+ });
338
+ break;
339
+ }
340
+ case "generateBatch": {
341
+ const startTime = Date.now();
342
+ const embeddings = await generateBatch(message.texts);
343
+ sendResponse({
344
+ type: "generateBatch",
345
+ requestId: message.requestId,
346
+ success: true,
347
+ embeddings,
348
+ inferenceTimeMs: Date.now() - startTime,
349
+ });
350
+ break;
351
+ }
352
+ case "dispose": {
353
+ await disposePipeline();
354
+ sendResponse({
355
+ type: "dispose",
356
+ requestId: message.requestId,
357
+ success: true,
358
+ });
359
+ break;
360
+ }
361
+ case "terminate": {
362
+ await disposePipeline();
363
+ sendResponse({
364
+ type: "terminate",
365
+ requestId: message.requestId,
366
+ success: true,
367
+ });
368
+ // Allow the response to be flushed before exiting
369
+ setTimeout(() => process.exit(0), 50);
370
+ break;
371
+ }
372
+ case "switch-provider": {
373
+ const targetProvider = message.provider;
374
+ // If switching to CUDA, verify availability first
375
+ if (targetProvider === "cuda") {
376
+ const canUseCuda = verifyCudaAvailability();
377
+ if (!canUseCuda) {
378
+ // Cannot switch to CUDA — respond with current (cpu) provider
379
+ sendResponse({
380
+ type: "switch-provider",
381
+ requestId: message.requestId,
382
+ success: true,
383
+ provider: "cpu",
384
+ });
385
+ break;
386
+ }
387
+ }
388
+ // Dispose current pipeline before switching
389
+ await disposePipeline();
390
+ // Update provider and config — mark as explicitly set so
391
+ // initializePipeline() won't override via detectExecutionProvider()
392
+ resolvedProvider = targetProvider;
393
+ providerExplicitlySet = true;
394
+ config = { ...config, device: targetProvider };
395
+ // eslint-disable-next-line no-console
396
+ console.log("[EmbeddingWorker] Switched provider to:", resolvedProvider);
397
+ sendResponse({
398
+ type: "switch-provider",
399
+ requestId: message.requestId,
400
+ success: true,
401
+ provider: resolvedProvider,
402
+ });
403
+ break;
404
+ }
405
+ case "release-gpu": {
406
+ // Dispose pipeline and revert to CPU
407
+ await disposePipeline();
408
+ resolvedProvider = "cpu";
409
+ providerExplicitlySet = true;
410
+ config = { ...config, device: "cpu" };
411
+ // eslint-disable-next-line no-console
412
+ console.log("[EmbeddingWorker] Released GPU, reverted to CPU");
413
+ sendResponse({
414
+ type: "release-gpu",
415
+ requestId: message.requestId,
416
+ success: true,
417
+ });
418
+ break;
419
+ }
420
+ default: {
421
+ // SEC-M2: Reject unknown message types for defense-in-depth
422
+ const unknownType = message.type ?? "unknown";
423
+ sendError(message.requestId ?? "unknown", unknownType, new Error(`Unknown worker message type: ${String(unknownType)}`));
424
+ break;
425
+ }
426
+ }
427
+ }
428
+ // =====================================================
429
+ // Setup parentPort listener
430
+ // =====================================================
431
+ if (!parentPort) {
432
+ throw new Error("worker-thread.ts must be run as a Worker Thread (no parentPort)");
433
+ }
434
+ parentPort.on("message", (message) => {
435
+ handleMessage(message).catch((error) => {
436
+ sendError(message.requestId, message.type, error);
437
+ });
438
+ });
439
+ // Export recycle count for monitoring (accessible via workerData if needed)
440
+ export { totalRecycles, inferencesSinceRecycle };
441
+ //# sourceMappingURL=worker-thread.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-thread.js","sourceRoot":"","sources":["../../src/embeddings/worker-thread.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @reftrixmcp/ml
3
+ * ML/Embedding and Search services for Reftrix
4
+ */
5
+ export { EmbeddingService, embeddingService, cosineSimilarity } from "./embeddings/index.js";
6
+ export type { EmbeddingTextType, EmbeddingServiceConfig, CacheStats, EmbeddingResult, BatchEmbeddingResult, } from "./embeddings/index.js";
7
+ export { StyleEmbeddingService, styleEmbeddingService, createStyleEmbedding, createBatchStyleEmbeddings, createQueryEmbedding, } from "./embeddings/index.js";
8
+ export type { StyleEmbeddingConfig } from "./embeddings/index.js";
9
+ export { VisionEmbeddingService, visionEmbeddingService, createVisionEmbedding, createBatchVisionEmbeddings, visionFeaturesToText, } from "./embeddings/index.js";
10
+ export type { VisionFeatures, VisionRhythm, VisionDensity, VisionGravity, VisionTheme, VisionEmbeddingServiceConfig, VisionCacheStats, } from "./embeddings/index.js";
11
+ export { DINOv2Service, DINOV2_EMBEDDING_DIMENSION, DINOV2_INPUT_SIZE } from "./dinov2/index.js";
12
+ export type { DINOv2ServiceConfig } from "./dinov2/index.js";
13
+ export type { DINOv2WorkerMessage, DINOv2WorkerResponse } from "./dinov2/index.js";
14
+ export { calculateRRF, mergeWithRRF, normalizeRRFScore, toRankedItems } from "./search/index.js";
15
+ export { executeHybridSearch } from "./search/index.js";
16
+ export { buildFulltextConditions, buildFulltextRankExpression } from "./search/index.js";
17
+ export type { SearchFilters, SearchOptions, HybridSearchOptions, SearchResult, SummarySearchResult, SearchResultItem, SummarySearchResultItem, VectorSearchRawResult, FullTextSearchRawResult, RankedItem, RRFScoredItem, HybridSearchConfig, HybridSearchResult, } from "./search/index.js";
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;GAGG;AAGH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC7F,YAAY,EACV,iBAAiB,EACjB,sBAAsB,EACtB,UAAU,EACV,eAAe,EACf,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAGlE,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,2BAA2B,EAC3B,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,cAAc,EACd,YAAY,EACZ,aAAa,EACb,aAAa,EACb,WAAW,EACX,4BAA4B,EAC5B,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACjG,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAGnF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACjG,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AACzF,YAAY,EACV,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,EACrB,uBAAuB,EACvB,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
1
+ // SPDX-FileCopyrightText: 2026 TKMD and Reftrix Contributors
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * @reftrixmcp/ml
5
+ * ML/Embedding and Search services for Reftrix
6
+ */
7
+ // Embedding service exports
8
+ export { EmbeddingService, embeddingService, cosineSimilarity } from "./embeddings/index.js";
9
+ // Style Feature Embedding exports
10
+ export { StyleEmbeddingService, styleEmbeddingService, createStyleEmbedding, createBatchStyleEmbeddings, createQueryEmbedding, } from "./embeddings/index.js";
11
+ // Vision Feature Embedding exports
12
+ export { VisionEmbeddingService, visionEmbeddingService, createVisionEmbedding, createBatchVisionEmbeddings, visionFeaturesToText, } from "./embeddings/index.js";
13
+ // DINOv2 visual embedding exports
14
+ export { DINOv2Service, DINOV2_EMBEDDING_DIMENSION, DINOV2_INPUT_SIZE } from "./dinov2/index.js";
15
+ // Search utilities exports (SearchService removed in v0.1.0)
16
+ export { calculateRRF, mergeWithRRF, normalizeRRFScore, toRankedItems } from "./search/index.js";
17
+ export { executeHybridSearch } from "./search/index.js";
18
+ export { buildFulltextConditions, buildFulltextRankExpression } from "./search/index.js";
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,yCAAyC;AAEzC;;;GAGG;AAEH,4BAA4B;AAC5B,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAS7F,kCAAkC;AAClC,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAG/B,mCAAmC;AACnC,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,2BAA2B,EAC3B,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAW/B,kCAAkC;AAClC,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAIjG,6DAA6D;AAC7D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACjG,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Full-text search SQL helpers for Hybrid Search.
3
+ *
4
+ * Provides shared SQL clause builders used across layout, motion,
5
+ * background, and narrative hybrid search implementations.
6
+ *
7
+ * @see TDA-HS-R2: DRY principle for fulltext SQL construction
8
+ */
9
+ /**
10
+ * Build WHERE conditions for PostgreSQL tsvector full-text search.
11
+ *
12
+ * Generates the standard three-part condition:
13
+ * 1. search_vector IS NOT NULL
14
+ * 2. plainto_tsquery('english', $N) <> ''::tsquery (skip empty queries)
15
+ * 3. search_vector @@ plainto_tsquery('english', $N) (actual match)
16
+ *
17
+ * @param searchVectorColumn - Fully qualified column name (e.g., 'se.search_vector')
18
+ * @param paramIndex - The $N parameter index for the query text
19
+ * @returns SQL condition string (without leading AND/WHERE)
20
+ */
21
+ export declare function buildFulltextConditions(searchVectorColumn: string, paramIndex: number): string;
22
+ /**
23
+ * Build ts_rank_cd expression for full-text search ranking.
24
+ *
25
+ * @param searchVectorColumn - Fully qualified column name (e.g., 'se.search_vector')
26
+ * @param paramIndex - The $N parameter index for the query text
27
+ * @returns SQL expression string for use in SELECT or ORDER BY
28
+ */
29
+ export declare function buildFulltextRankExpression(searchVectorColumn: string, paramIndex: number): string;
30
+ //# sourceMappingURL=fulltext-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fulltext-helpers.d.ts","sourceRoot":"","sources":["../../src/search/fulltext-helpers.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AAEH;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAM9F;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,kBAAkB,EAAE,MAAM,EAC1B,UAAU,EAAE,MAAM,GACjB,MAAM,CAER"}
@@ -0,0 +1,40 @@
1
+ // SPDX-FileCopyrightText: 2026 TKMD and Reftrix Contributors
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Full-text search SQL helpers for Hybrid Search.
5
+ *
6
+ * Provides shared SQL clause builders used across layout, motion,
7
+ * background, and narrative hybrid search implementations.
8
+ *
9
+ * @see TDA-HS-R2: DRY principle for fulltext SQL construction
10
+ */
11
+ /**
12
+ * Build WHERE conditions for PostgreSQL tsvector full-text search.
13
+ *
14
+ * Generates the standard three-part condition:
15
+ * 1. search_vector IS NOT NULL
16
+ * 2. plainto_tsquery('english', $N) <> ''::tsquery (skip empty queries)
17
+ * 3. search_vector @@ plainto_tsquery('english', $N) (actual match)
18
+ *
19
+ * @param searchVectorColumn - Fully qualified column name (e.g., 'se.search_vector')
20
+ * @param paramIndex - The $N parameter index for the query text
21
+ * @returns SQL condition string (without leading AND/WHERE)
22
+ */
23
+ export function buildFulltextConditions(searchVectorColumn, paramIndex) {
24
+ return [
25
+ `${searchVectorColumn} IS NOT NULL`,
26
+ `plainto_tsquery('english', $${paramIndex}) <> ''::tsquery`,
27
+ `${searchVectorColumn} @@ plainto_tsquery('english', $${paramIndex})`,
28
+ ].join(" AND ");
29
+ }
30
+ /**
31
+ * Build ts_rank_cd expression for full-text search ranking.
32
+ *
33
+ * @param searchVectorColumn - Fully qualified column name (e.g., 'se.search_vector')
34
+ * @param paramIndex - The $N parameter index for the query text
35
+ * @returns SQL expression string for use in SELECT or ORDER BY
36
+ */
37
+ export function buildFulltextRankExpression(searchVectorColumn, paramIndex) {
38
+ return `ts_rank_cd(${searchVectorColumn}, plainto_tsquery('english', $${paramIndex}))`;
39
+ }
40
+ //# sourceMappingURL=fulltext-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fulltext-helpers.js","sourceRoot":"","sources":["../../src/search/fulltext-helpers.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,yCAAyC;AAEzC;;;;;;;GAOG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,uBAAuB,CAAC,kBAA0B,EAAE,UAAkB;IACpF,OAAO;QACL,GAAG,kBAAkB,cAAc;QACnC,+BAA+B,UAAU,kBAAkB;QAC3D,GAAG,kBAAkB,mCAAmC,UAAU,GAAG;KACtE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CACzC,kBAA0B,EAC1B,UAAkB;IAElB,OAAO,cAAc,kBAAkB,iCAAiC,UAAU,IAAI,CAAC;AACzF,CAAC"}
@@ -0,0 +1,40 @@
1
+ import type { RankedItem } from "./rrf.js";
2
+ /**
3
+ * Configuration for hybrid search execution
4
+ */
5
+ export interface HybridSearchConfig {
6
+ /** Weight for vector search results (default 0.6) */
7
+ vectorWeight?: number;
8
+ /** Weight for full-text search results (default 0.4) */
9
+ fulltextWeight?: number;
10
+ /** RRF constant k (default 60) */
11
+ k?: number;
12
+ }
13
+ /**
14
+ * Result from hybrid search with normalized similarity score
15
+ */
16
+ export interface HybridSearchResult {
17
+ id: string;
18
+ /** Normalized similarity score (0-1) */
19
+ similarity: number;
20
+ /** Source information for debugging */
21
+ source: {
22
+ vectorRank?: number;
23
+ fulltextRank?: number;
24
+ };
25
+ /** Additional data from the search result */
26
+ data: Record<string, unknown>;
27
+ }
28
+ /**
29
+ * Execute hybrid search by combining vector and full-text search results with RRF
30
+ *
31
+ * Both search functions are executed in parallel via Promise.all for minimum latency.
32
+ * Results are merged using Reciprocal Rank Fusion (RRF) with configurable weights.
33
+ *
34
+ * @param vectorSearchFn - Function that returns vector search results (ranked by cosine similarity)
35
+ * @param fulltextSearchFn - Function that returns full-text search results (ranked by ts_rank_cd)
36
+ * @param config - Optional hybrid search configuration
37
+ * @returns Merged results sorted by normalized RRF similarity score
38
+ */
39
+ export declare function executeHybridSearch(vectorSearchFn: () => Promise<RankedItem[]>, fulltextSearchFn: () => Promise<RankedItem[]>, config?: HybridSearchConfig): Promise<HybridSearchResult[]>;
40
+ //# sourceMappingURL=hybrid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid.d.ts","sourceRoot":"","sources":["../../src/search/hybrid.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,UAAU,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kCAAkC;IAClC,CAAC,CAAC,EAAE,MAAM,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,MAAM,EAAE;QACN,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAQD;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,cAAc,EAAE,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC,EAC3C,gBAAgB,EAAE,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC,EAC7C,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,kBAAkB,EAAE,CAAC,CA0C/B"}