@zuvia-software-solutions/code-mapper 2.6.2 → 2.6.3

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.
@@ -9,20 +9,28 @@
9
9
  import { pipeline } from '@huggingface/transformers';
10
10
  const MODEL_ID = 'Xenova/bge-small-en-v1.5';
11
11
  async function main() {
12
- // Load model
13
12
  const extractor = await pipeline('feature-extraction', MODEL_ID, { quantized: true });
14
13
  process.send({ type: 'ready' });
15
14
  // Process messages from parent
16
15
  process.on('message', async (msg) => {
17
16
  if (msg.type === 'embed') {
18
17
  const results = [];
19
- for (const item of msg.items) {
20
- try {
21
- const result = await extractor(item.text, { pooling: 'cls', normalize: true });
22
- results.push({ nodeId: item.nodeId, vec: Array.from(result.data) });
18
+ try {
19
+ const texts = msg.items.map((item) => item.text);
20
+ const batchResult = await extractor(texts, { pooling: 'cls', normalize: true });
21
+ const dims = batchResult.dims?.[1] ?? 384;
22
+ const flat = batchResult.data;
23
+ for (let i = 0; i < msg.items.length; i++) {
24
+ results.push({ nodeId: msg.items[i].nodeId, vec: Array.from(flat.subarray(i * dims, (i + 1) * dims)) });
23
25
  }
24
- catch {
25
- // Skip failed embeddings
26
+ }
27
+ catch {
28
+ for (const item of msg.items) {
29
+ try {
30
+ const result = await extractor(item.text, { pooling: 'cls', normalize: true });
31
+ results.push({ nodeId: item.nodeId, vec: Array.from(result.data) });
32
+ }
33
+ catch { /* skip */ }
26
34
  }
27
35
  }
28
36
  process.send({ type: 'results', results, batchId: msg.batchId });
@@ -21,9 +21,11 @@ export async function initNlEmbedder() {
21
21
  return loadPromise;
22
22
  loadPromise = (async () => {
23
23
  const { pipeline, env } = await import('@huggingface/transformers');
24
+ const os = await import('os');
25
+ const cpuCount = os.cpus().length;
24
26
  // Use all available CPU threads for ONNX inference
25
27
  if (env.backends?.onnx?.wasm) {
26
- env.backends.onnx.wasm.numThreads = Math.max(1, (await import('os')).cpus().length);
28
+ env.backends.onnx.wasm.numThreads = Math.max(1, cpuCount);
27
29
  }
28
30
  extractor = await pipeline('feature-extraction', MODEL_ID, { quantized: true });
29
31
  })();
@@ -44,14 +46,15 @@ export async function nlEmbed(text) {
44
46
  export async function nlEmbedBatch(texts) {
45
47
  if (!extractor)
46
48
  await initNlEmbedder();
47
- const BATCH = 32; // sub-batch size — balances throughput vs memory
49
+ const BATCH = 64;
48
50
  const results = [];
49
51
  for (let i = 0; i < texts.length; i += BATCH) {
50
52
  const batch = texts.slice(i, i + BATCH);
51
- // Process sub-batch transformers.js handles arrays
52
- const batchResults = await Promise.all(batch.map(text => extractor(text, { pooling: 'cls', normalize: true })));
53
- for (const result of batchResults) {
54
- results.push(Array.from(result.data));
53
+ const batchResult = await extractor(batch, { pooling: 'cls', normalize: true });
54
+ const dims = batchResult.dims?.[1] ?? 384;
55
+ const flat = batchResult.data;
56
+ for (let j = 0; j < batch.length; j++) {
57
+ results.push(Array.from(flat.subarray(j * dims, (j + 1) * dims)));
55
58
  }
56
59
  }
57
60
  return results;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zuvia-software-solutions/code-mapper",
3
- "version": "2.6.2",
3
+ "version": "2.6.3",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": "Abhigyan Patwari",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",