gm-plugkit 2.0.1100 → 2.0.1101

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-plugkit",
3
- "version": "2.0.1100",
3
+ "version": "2.0.1101",
4
4
  "description": "Bootstrap and daemon-spawn tool for gm plugkit binary. Downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Includes plugkit-wasm-wrapper for WASM-based spool watching.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -7,8 +7,24 @@ import { spawn, spawnSync } from 'child_process';
7
7
  const KV_DIR = path.join(os.homedir(), '.claude', 'gm-tools', 'kv');
8
8
  fs.mkdirSync(KV_DIR, { recursive: true });
9
9
 
10
- const RS_LEARN_URL = process.env.RS_LEARN_URL || 'http://127.0.0.1:8000';
10
+ const ACPTOAPI_URL = process.env.ACPTOAPI_URL || 'http://127.0.0.1:4800';
11
11
  const VEC_K_DEFAULT = 10;
12
+ const EMBED_MODEL_DEFAULT = process.env.EMBED_MODEL || 'mistral/mistral-embed';
13
+ const INFERENCE_MODEL_DEFAULT = process.env.INFERENCE_MODEL || 'groq/llama-3.3-70b-versatile';
14
+
15
+ function failLoud(verb, status, detail) {
16
+ const msg = `[plugkit-wasm] ${verb} FAILED: ${detail}`;
17
+ console.error(msg);
18
+ return { ok: false, verb, error: detail, status: status || 0 };
19
+ }
20
+
21
+ function cosineSim(a, b) {
22
+ if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return 0;
23
+ let dot = 0, na = 0, nb = 0;
24
+ for (let i = 0; i < a.length; i++) { dot += a[i] * b[i]; na += a[i] * a[i]; nb += b[i] * b[i]; }
25
+ if (na === 0 || nb === 0) return 0;
26
+ return dot / (Math.sqrt(na) * Math.sqrt(nb));
27
+ }
12
28
 
13
29
  const browserSessions = new Map();
14
30
  let nextBrowserSessionId = 1;
@@ -192,23 +208,44 @@ function makeHostFunctions(instanceRef) {
192
208
  let parsedQ;
193
209
  try { parsedQ = JSON.parse(raw); } catch (_) { parsedQ = { query: raw }; }
194
210
  const q = parsedQ.query || raw;
195
- const scope = parsedQ.scope || 'all';
211
+ const namespace = parsedQ.namespace || 'default';
212
+ const extractVec = (e) => {
213
+ if (Array.isArray(e)) return e;
214
+ if (Array.isArray(e?.data?.[0]?.embedding)) return e.data[0].embedding;
215
+ if (Array.isArray(e?.embedding)) return e.embedding;
216
+ return null;
217
+ };
218
+ const queryEmbedding = extractVec(parsedQ.embedding);
196
219
  const k_ = k > 0 ? k : VEC_K_DEFAULT;
197
- const body = JSON.stringify({ query: q, limit: k_, scope });
198
- const result = spawnSync(process.execPath, ['-e', `
199
- fetch('${RS_LEARN_URL}/search', { method: 'POST', headers: { 'content-type': 'application/json' }, body: ${JSON.stringify(body)} })
200
- .then(r => r.text().then(t => process.stdout.write(t)))
201
- .catch(e => process.stdout.write(JSON.stringify({ error: e.message })));
202
- `], { encoding: 'utf-8', timeout: 5000 });
203
- if (result.status !== 0 || !result.stdout) return writeWasmJson(instanceRef.value, []);
204
- try {
205
- const parsed = JSON.parse(result.stdout);
206
- const hits = parsed.hits || parsed.results || parsed.episodes || [];
207
- return writeWasmJson(instanceRef.value, hits);
208
- } catch (_) {
220
+ if (!queryEmbedding) {
221
+ if (process.env.PLUGKIT_DEBUG) console.error('[plugkit-wasm] host_vec_search: no embedding in query, raw=', raw.slice(0, 200));
209
222
  return writeWasmJson(instanceRef.value, []);
210
223
  }
224
+ const vecDir = path.join(KV_DIR, `${namespace}-vec`.replace(/[^A-Za-z0-9._-]/g, '_'));
225
+ const dataDir = path.join(KV_DIR, namespace.replace(/[^A-Za-z0-9._-]/g, '_'));
226
+ if (!fs.existsSync(vecDir) || !fs.existsSync(dataDir)) {
227
+ return writeWasmJson(instanceRef.value, []);
228
+ }
229
+ const scored = [];
230
+ for (const f of fs.readdirSync(vecDir)) {
231
+ if (!f.endsWith('.json')) continue;
232
+ let emb;
233
+ try { emb = JSON.parse(fs.readFileSync(path.join(vecDir, f), 'utf-8')); }
234
+ catch (_) { continue; }
235
+ const vector = Array.isArray(emb?.data?.[0]?.embedding) ? emb.data[0].embedding
236
+ : Array.isArray(emb?.embedding) ? emb.embedding
237
+ : Array.isArray(emb) ? emb : null;
238
+ if (!vector) continue;
239
+ const score = cosineSim(queryEmbedding, vector);
240
+ const key = f.replace(/\.json$/, '');
241
+ const valuePath = path.join(dataDir, `${key}.json`);
242
+ const text = fs.existsSync(valuePath) ? fs.readFileSync(valuePath, 'utf-8') : '';
243
+ scored.push({ key, text, score });
244
+ }
245
+ scored.sort((a, b) => b.score - a.score);
246
+ return writeWasmJson(instanceRef.value, scored.slice(0, k_));
211
247
  } catch (e) {
248
+ console.error('[plugkit-wasm] host_vec_search error:', e.message);
212
249
  return writeWasmJson(instanceRef.value, []);
213
250
  }
214
251
  },
@@ -217,15 +254,20 @@ function makeHostFunctions(instanceRef) {
217
254
  try {
218
255
  const text = readWasmStr(instanceRef.value, textPtr, textLen);
219
256
  if (!text) return 0n;
220
- const body = JSON.stringify({ text });
257
+ const body = JSON.stringify({ model: EMBED_MODEL_DEFAULT, input: text });
221
258
  const result = spawnSync(process.execPath, ['-e', `
222
- fetch('${RS_LEARN_URL}/embed', { method: 'POST', headers: { 'content-type': 'application/json' }, body: ${JSON.stringify(body)} })
223
- .then(r => r.text().then(t => process.stdout.write(t)))
224
- .catch(e => process.stdout.write(''));
225
- `], { encoding: 'utf-8', timeout: 5000 });
226
- if (result.status !== 0 || !result.stdout) return 0n;
259
+ fetch('${ACPTOAPI_URL}/v1/embeddings', { method: 'POST', headers: { 'content-type': 'application/json' }, body: ${JSON.stringify(body)} })
260
+ .then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.text(); })
261
+ .then(t => process.stdout.write(t))
262
+ .catch(e => { process.stderr.write('embed-error: ' + e.message); process.exit(2); });
263
+ `], { encoding: 'utf-8', timeout: 30000 });
264
+ if (result.status !== 0 || !result.stdout) {
265
+ console.error('[plugkit-wasm] host_vec_embed FAILED:', result.stderr || 'no response');
266
+ return 0n;
267
+ }
227
268
  return writeWasmStr(instanceRef.value, result.stdout);
228
269
  } catch (e) {
270
+ console.error('[plugkit-wasm] host_vec_embed exception:', e.message);
229
271
  return 0n;
230
272
  }
231
273
  },