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 +1 -1
- package/plugkit-wasm-wrapper.js +62 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-plugkit",
|
|
3
|
-
"version": "2.0.
|
|
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": {
|
package/plugkit-wasm-wrapper.js
CHANGED
|
@@ -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
|
|
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 (
|
|
393
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
},
|
|
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
|
-
|
|
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);
|