@kelceyp/caw-server 1.0.197 → 1.0.198

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.
@@ -21,6 +21,17 @@
21
21
 
22
22
  import { createInterface } from 'readline';
23
23
 
24
+ const pad = (n) => String(n).padStart(2, '0');
25
+ const pad3 = (n) => String(n).padStart(3, '0');
26
+ const formatTimestamp = () => {
27
+ const now = new Date();
28
+ const h = now.getHours();
29
+ const ampm = h >= 12 ? 'pm' : 'am';
30
+ const h12 = h % 12 || 12;
31
+ return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}` +
32
+ ` ${pad(h12)}:${pad(now.getMinutes())}:${pad(now.getSeconds())}.${pad3(now.getMilliseconds())} ${ampm}`;
33
+ };
34
+
24
35
  const MODEL_NAME = process.env.EMBEDDING_MODEL || 'nomic-ai/nomic-embed-text-v1.5';
25
36
  const CACHE_DIR = process.env.EMBEDDING_CACHE_DIR || null;
26
37
 
@@ -50,17 +61,17 @@ const run = async () => {
50
61
  },
51
62
  progress_callback: (progress) => {
52
63
  if (progress.status === 'download') {
53
- process.stderr.write(`[EmbeddingWorker] Downloading: ${progress.file} (${Math.round((progress.loaded / progress.total) * 100)}%)\n`);
64
+ process.stderr.write(`${formatTimestamp()} [EmbeddingWorker] Downloading: ${progress.file} (${Math.round((progress.loaded / progress.total) * 100)}%)\n`);
54
65
  } else if (progress.status === 'ready') {
55
66
  const suffix = progress.file ? `: ${progress.file}` : '';
56
- process.stderr.write(`[EmbeddingWorker] Ready${suffix}\n`);
67
+ process.stderr.write(`${formatTimestamp()} [EmbeddingWorker] Ready${suffix}\n`);
57
68
  }
58
69
  }
59
70
  });
60
71
 
61
72
  // Log loaded model details and baseline memory
62
73
  const rss = Math.round(process.memoryUsage().rss / 1024 / 1024);
63
- process.stderr.write(`[EmbeddingWorker] Model loaded. RSS: ${rss}MB\n`);
74
+ process.stderr.write(`${formatTimestamp()} [EmbeddingWorker] Model loaded. RSS: ${rss}MB\n`);
64
75
 
65
76
  sendLine({ ready: true });
66
77
  } catch (err) {
@@ -81,26 +92,41 @@ const run = async () => {
81
92
  return;
82
93
  }
83
94
 
84
- const { texts } = req;
95
+ const { texts, maxLength } = req;
85
96
  if (!Array.isArray(texts)) {
86
97
  sendLine({ error: 'Request must have a texts array' });
87
98
  return;
88
99
  }
89
100
 
90
- try {
91
- const output = await pipe(texts, { pooling: 'mean', normalize: false });
92
- // Serialise: output.data is a flat Float32Array [batch * dims]
101
+ const extractVectors = (output, count) => {
93
102
  const dims = output.dims[output.dims.length - 1];
94
103
  const vectors = [];
95
- for (let i = 0; i < texts.length; i++) {
104
+ for (let i = 0; i < count; i++) {
96
105
  const start = i * dims;
97
- const end = start + dims;
98
- vectors.push(Array.from(output.data.slice(start, end)));
106
+ vectors.push(Array.from(output.data.slice(start, start + dims)));
99
107
  }
100
108
  output.dispose();
109
+ return vectors;
110
+ };
111
+
112
+ try {
113
+ let output;
114
+ if (maxLength !== undefined) {
115
+ const paddingOptions = { pooling: 'mean', normalize: false, padding: 'max_length', max_length: maxLength };
116
+ try {
117
+ output = await pipe(texts, paddingOptions);
118
+ } catch (_paddingErr) {
119
+ process.stderr.write(`${formatTimestamp()} [EmbeddingWorker] padding options unsupported, retrying without padding\n`);
120
+ output = await pipe(texts, { pooling: 'mean', normalize: false });
121
+ }
122
+ } else {
123
+ output = await pipe(texts, { pooling: 'mean', normalize: false });
124
+ }
125
+ const vectors = extractVectors(output, texts.length);
101
126
  embedCallCount++;
102
127
  const embedRss = Math.round(process.memoryUsage().rss / 1024 / 1024);
103
- process.stderr.write(`[EmbeddingWorker] Embed #${embedCallCount}: ${texts.length} texts, RSS: ${embedRss}MB\n`);
128
+ const shapeStr = maxLength !== undefined ? `[${texts.length}×${maxLength}]` : `[${texts.length}×var]`;
129
+ process.stderr.write(`${formatTimestamp()} [EmbeddingWorker] Embed #${embedCallCount}: shape=${shapeStr}, RSS: ${embedRss}MB\n`);
104
130
  sendLine({ vectors });
105
131
  } catch (err) {
106
132
  sendLine({ error: `Embedding failed: ${err.message}` });