gm-plugkit 2.0.1107 → 2.0.1108

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.1107",
3
+ "version": "2.0.1108",
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": {
@@ -12,12 +12,6 @@ const VEC_K_DEFAULT = 10;
12
12
  const EMBED_MODEL_DEFAULT = process.env.EMBED_MODEL || 'mistral/mistral-embed';
13
13
  const INFERENCE_MODEL_DEFAULT = process.env.INFERENCE_MODEL || 'groq/llama-3.3-70b-versatile';
14
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
15
  function cosineSim(a, b) {
22
16
  if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return 0;
23
17
  let dot = 0, na = 0, nb = 0;
@@ -383,14 +377,25 @@ async function runSpoolWatcher(instance, spoolDir) {
383
377
  console.log(`[plugkit-wasm] plugkit v${resolveVersion(instance)} (wasm)`);
384
378
  console.log(`[plugkit-wasm] watching ${inDir}`);
385
379
 
386
- const processed = new Set();
380
+ const PROCESSED_MAX = 10000;
381
+ const processed = new Map();
382
+ function markProcessed(key) {
383
+ processed.set(key, Date.now());
384
+ if (processed.size > PROCESSED_MAX) {
385
+ const oldest = processed.keys().next().value;
386
+ processed.delete(oldest);
387
+ }
388
+ }
389
+ function isProcessed(key) { return processed.has(key); }
390
+ function unmarkProcessed(key) { processed.delete(key); }
391
+
387
392
  const dispatch = instance.exports.dispatch_verb;
388
393
  if (!dispatch) throw new Error('dispatch_verb not exported');
389
394
 
390
395
  const processFile = async (filePath) => {
391
396
  const key = path.relative(inDir, filePath);
392
- if (processed.has(key)) return;
393
- processed.add(key);
397
+ if (isProcessed(key)) return;
398
+ markProcessed(key);
394
399
 
395
400
  try {
396
401
  const content = fs.readFileSync(filePath, 'utf8');
@@ -423,7 +428,7 @@ async function runSpoolWatcher(instance, spoolDir) {
423
428
  try { instance.exports.plugkit_free(ptr, len); } catch (_) {}
424
429
 
425
430
  try { if (fs.existsSync(filePath)) fs.unlinkSync(filePath); } catch (_) {}
426
- processed.delete(key);
431
+ unmarkProcessed(key);
427
432
  } catch (e) {
428
433
  console.error(`[plugkit-wasm] error processing ${key}: ${e.message}`);
429
434
  const taskBase = path.basename(filePath, path.extname(filePath));
@@ -435,7 +440,7 @@ async function runSpoolWatcher(instance, spoolDir) {
435
440
  fs.writeFileSync(path.join(outDir, outName), JSON.stringify({ ok: false, error: e.message }));
436
441
  } catch (_) {}
437
442
  try { fs.unlinkSync(filePath); } catch (_) {}
438
- processed.delete(key);
443
+ unmarkProcessed(key);
439
444
  }
440
445
  };
441
446
 
@@ -462,12 +467,51 @@ async function runSpoolWatcher(instance, spoolDir) {
462
467
  try { fs.writeFileSync(heartbeatPath, String(Date.now())); } catch (_) {}
463
468
  }, 5000);
464
469
 
465
- const pollDeadline = setInterval(async () => {
470
+ const pollInterval = setInterval(async () => {
466
471
  const existing = walkDir(inDir);
467
472
  for (const fullPath of existing) {
468
473
  await processFile(fullPath);
469
474
  }
470
- }, 250);
475
+ }, 5000);
476
+
477
+ setInterval(() => {
478
+ try {
479
+ const cutoff = Date.now() - 3600_000;
480
+ for (const entry of fs.readdirSync(outDir)) {
481
+ try {
482
+ const fp = path.join(outDir, entry);
483
+ const s = fs.statSync(fp);
484
+ if (s.mtimeMs < cutoff) fs.unlinkSync(fp);
485
+ } catch (_) {}
486
+ }
487
+ } catch (_) {}
488
+ }, 60_000);
489
+
490
+ setInterval(() => {
491
+ try {
492
+ const cutoff = Date.now() - 600_000;
493
+ const walk = (dir) => {
494
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
495
+ const fp = path.join(dir, entry.name);
496
+ if (entry.isDirectory()) walk(fp);
497
+ else if (entry.isFile()) {
498
+ const s = fs.statSync(fp);
499
+ if (s.mtimeMs < cutoff) {
500
+ const rel = path.relative(inDir, fp);
501
+ const verbDir = path.dirname(rel);
502
+ const base = path.basename(fp, path.extname(fp));
503
+ const outName = verbDir === '.' ? `${base}.json` : `${verbDir}-${base}.json`;
504
+ try {
505
+ fs.writeFileSync(path.join(outDir, outName), JSON.stringify({ ok: false, error: 'stale input — never dispatched or watcher crash mid-flight' }));
506
+ } catch (_) {}
507
+ try { fs.unlinkSync(fp); } catch (_) {}
508
+ }
509
+ }
510
+ }
511
+ };
512
+ walk(inDir);
513
+ } catch (_) {}
514
+ }, 300_000);
471
515
 
472
516
  const existing = walkDir(inDir);
473
517
  for (const fullPath of existing) {
@@ -523,7 +567,7 @@ async function runSpoolWatcher(instance, spoolDir) {
523
567
  await runSpoolWatcher(instance, spoolDir);
524
568
  } else if (args[0] === 'dispatch') {
525
569
  const verb = args[1] || '';
526
- const body = args[2] || '{}';
570
+ const body = args.length >= 3 ? args[2] : '';
527
571
  const dispatch = instance.exports.dispatch_verb;
528
572
  const verbBytes = new TextEncoder().encode(verb);
529
573
  const bodyBytes = new TextEncoder().encode(body);
@@ -536,7 +580,10 @@ async function runSpoolWatcher(instance, spoolDir) {
536
580
  const len = Number(result >> 32n);
537
581
  const out = new TextDecoder().decode(new Uint8Array(instance.exports.memory.buffer, ptr, len));
538
582
  process.stdout.write(out);
539
- process.exit(0);
583
+ let parsed;
584
+ try { parsed = JSON.parse(out); } catch (_) { parsed = null; }
585
+ const failed = parsed && parsed.ok === false;
586
+ process.exit(failed ? 2 : 0);
540
587
  } else {
541
588
  console.log('[plugkit-wasm] args:', args.join(' '));
542
589
  process.exit(0);