@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.
- package/LICENSE +661 -0
- package/dist/dinov2/index.d.ts +7 -0
- package/dist/dinov2/index.d.ts.map +1 -0
- package/dist/dinov2/index.js +7 -0
- package/dist/dinov2/index.js.map +1 -0
- package/dist/dinov2/service.d.ts +106 -0
- package/dist/dinov2/service.d.ts.map +1 -0
- package/dist/dinov2/service.js +446 -0
- package/dist/dinov2/service.js.map +1 -0
- package/dist/dinov2/worker-thread-types.d.ts +77 -0
- package/dist/dinov2/worker-thread-types.d.ts.map +1 -0
- package/dist/dinov2/worker-thread-types.js +4 -0
- package/dist/dinov2/worker-thread-types.js.map +1 -0
- package/dist/dinov2/worker-thread.d.ts +2 -0
- package/dist/dinov2/worker-thread.d.ts.map +1 -0
- package/dist/dinov2/worker-thread.js +231 -0
- package/dist/dinov2/worker-thread.js.map +1 -0
- package/dist/embeddings/index.d.ts +12 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +13 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/multimodal-embedding.service.d.ts +400 -0
- package/dist/embeddings/multimodal-embedding.service.d.ts.map +1 -0
- package/dist/embeddings/multimodal-embedding.service.js +650 -0
- package/dist/embeddings/multimodal-embedding.service.js.map +1 -0
- package/dist/embeddings/service.d.ts +261 -0
- package/dist/embeddings/service.d.ts.map +1 -0
- package/dist/embeddings/service.js +1093 -0
- package/dist/embeddings/service.js.map +1 -0
- package/dist/embeddings/style-embedding.service.d.ts +117 -0
- package/dist/embeddings/style-embedding.service.d.ts.map +1 -0
- package/dist/embeddings/style-embedding.service.js +157 -0
- package/dist/embeddings/style-embedding.service.js.map +1 -0
- package/dist/embeddings/types.d.ts +83 -0
- package/dist/embeddings/types.d.ts.map +1 -0
- package/dist/embeddings/types.js +4 -0
- package/dist/embeddings/types.js.map +1 -0
- package/dist/embeddings/vision-embedding.service.d.ts +70 -0
- package/dist/embeddings/vision-embedding.service.d.ts.map +1 -0
- package/dist/embeddings/vision-embedding.service.js +221 -0
- package/dist/embeddings/vision-embedding.service.js.map +1 -0
- package/dist/embeddings/vision-embedding.types.d.ts +102 -0
- package/dist/embeddings/vision-embedding.types.d.ts.map +1 -0
- package/dist/embeddings/vision-embedding.types.js +4 -0
- package/dist/embeddings/vision-embedding.types.js.map +1 -0
- package/dist/embeddings/worker-thread-types.d.ts +152 -0
- package/dist/embeddings/worker-thread-types.d.ts.map +1 -0
- package/dist/embeddings/worker-thread-types.js +4 -0
- package/dist/embeddings/worker-thread-types.js.map +1 -0
- package/dist/embeddings/worker-thread.d.ts +4 -0
- package/dist/embeddings/worker-thread.d.ts.map +1 -0
- package/dist/embeddings/worker-thread.js +441 -0
- package/dist/embeddings/worker-thread.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/search/fulltext-helpers.d.ts +30 -0
- package/dist/search/fulltext-helpers.d.ts.map +1 -0
- package/dist/search/fulltext-helpers.js +40 -0
- package/dist/search/fulltext-helpers.js.map +1 -0
- package/dist/search/hybrid.d.ts +40 -0
- package/dist/search/hybrid.d.ts.map +1 -0
- package/dist/search/hybrid.js +61 -0
- package/dist/search/hybrid.js.map +1 -0
- package/dist/search/index.d.ts +12 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +11 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/rrf.d.ts +69 -0
- package/dist/search/rrf.d.ts.map +1 -0
- package/dist/search/rrf.js +108 -0
- package/dist/search/rrf.js.map +1 -0
- package/dist/search/types.d.ts +130 -0
- package/dist/search/types.d.ts.map +1 -0
- package/dist/search/types.js +4 -0
- package/dist/search/types.js.map +1 -0
- package/package.json +65 -0
- package/src/dinov2/index.ts +21 -0
- package/src/dinov2/service.ts +539 -0
- package/src/dinov2/worker-thread-types.ts +103 -0
- package/src/dinov2/worker-thread.ts +306 -0
- package/src/embeddings/index.ts +74 -0
- package/src/embeddings/multimodal-embedding.service.ts +992 -0
- package/src/embeddings/service.ts +1287 -0
- package/src/embeddings/style-embedding.service.ts +201 -0
- package/src/embeddings/types.ts +95 -0
- package/src/embeddings/vision-embedding.service.ts +273 -0
- package/src/embeddings/vision-embedding.types.ts +117 -0
- package/src/embeddings/worker-thread-types.ts +194 -0
- package/src/embeddings/worker-thread.ts +529 -0
- package/src/index.ts +70 -0
- package/src/search/fulltext-helpers.ts +45 -0
- package/src/search/hybrid.ts +107 -0
- package/src/search/index.ts +25 -0
- package/src/search/rrf.ts +154 -0
- 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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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|