modelstat 0.0.39 → 0.0.42
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/dist/cli.mjs +262 -84
- package/dist/cli.mjs.map +1 -1
- package/package.json +3 -2
- package/scripts/postinstall.mjs +19 -114
- package/vendor/tray-mac/Sources/ModelstatTray/main.swift +133 -41
package/dist/cli.mjs
CHANGED
|
@@ -32612,10 +32612,14 @@ var init_http = __esm({
|
|
|
32612
32612
|
return { kind: "drop", reason: decision.reason };
|
|
32613
32613
|
}
|
|
32614
32614
|
if (decision.type === "reauth") {
|
|
32615
|
+
await res.body?.cancel().catch(() => {
|
|
32616
|
+
});
|
|
32615
32617
|
const ok = await this.opts.auth.onInvalidToken();
|
|
32616
32618
|
if (!ok) return { kind: "drop", reason: "reauth_failed" };
|
|
32617
32619
|
continue;
|
|
32618
32620
|
}
|
|
32621
|
+
await res.body?.cancel().catch(() => {
|
|
32622
|
+
});
|
|
32619
32623
|
this.opts.logger.warn("ingest backoff", {
|
|
32620
32624
|
status: res.status,
|
|
32621
32625
|
delay_ms: decision.delayMs,
|
|
@@ -44002,6 +44006,7 @@ var init_config2 = __esm({
|
|
|
44002
44006
|
userEmail: null,
|
|
44003
44007
|
defaultOrgId: null,
|
|
44004
44008
|
cursor: {},
|
|
44009
|
+
segmentsSent: 0,
|
|
44005
44010
|
processingVersion: null
|
|
44006
44011
|
}
|
|
44007
44012
|
});
|
|
@@ -44101,6 +44106,18 @@ var init_config2 = __esm({
|
|
|
44101
44106
|
wipeCursors() {
|
|
44102
44107
|
store.set("cursor", {});
|
|
44103
44108
|
},
|
|
44109
|
+
/** Lifetime tally of segments uploaded from this machine. Survives
|
|
44110
|
+
* daemon restarts so "total sent" keeps climbing across reboots. */
|
|
44111
|
+
get segmentsSent() {
|
|
44112
|
+
return store.get("segmentsSent") ?? 0;
|
|
44113
|
+
},
|
|
44114
|
+
/** Add to the lifetime tally and return the new total. Persisted
|
|
44115
|
+
* synchronously (same cadence as cursor writes during a scan). */
|
|
44116
|
+
bumpSegmentsSent(n) {
|
|
44117
|
+
const next = (store.get("segmentsSent") ?? 0) + n;
|
|
44118
|
+
store.set("segmentsSent", next);
|
|
44119
|
+
return next;
|
|
44120
|
+
},
|
|
44104
44121
|
get processingVersion() {
|
|
44105
44122
|
return store.get("processingVersion");
|
|
44106
44123
|
},
|
|
@@ -44371,7 +44388,7 @@ var init_cognition = __esm({
|
|
|
44371
44388
|
});
|
|
44372
44389
|
|
|
44373
44390
|
// ../../packages/companion-core/src/pipeline/index.ts
|
|
44374
|
-
async function buildSegmentsForSession(events, adapters2) {
|
|
44391
|
+
async function buildSegmentsForSession(events, adapters2, onProgress) {
|
|
44375
44392
|
if (events.length === 0) return [];
|
|
44376
44393
|
const bySession = /* @__PURE__ */ new Map();
|
|
44377
44394
|
for (const ev of events) {
|
|
@@ -44379,14 +44396,22 @@ async function buildSegmentsForSession(events, adapters2) {
|
|
|
44379
44396
|
arr.push(ev);
|
|
44380
44397
|
bySession.set(ev.session_id, arr);
|
|
44381
44398
|
}
|
|
44399
|
+
const sessions = [...bySession.entries()];
|
|
44382
44400
|
const out = [];
|
|
44383
|
-
for (
|
|
44384
|
-
const
|
|
44401
|
+
for (let si = 0; si < sessions.length; si++) {
|
|
44402
|
+
const [sessionId, evs] = sessions[si];
|
|
44403
|
+
const segs = await buildForOneSession(
|
|
44404
|
+
sessionId,
|
|
44405
|
+
evs,
|
|
44406
|
+
adapters2,
|
|
44407
|
+
onProgress ? (segment, segmentTotal) => onProgress({ session: si + 1, sessionTotal: sessions.length, segment, segmentTotal }) : void 0
|
|
44408
|
+
);
|
|
44385
44409
|
out.push(...segs);
|
|
44386
44410
|
}
|
|
44387
44411
|
return out;
|
|
44388
44412
|
}
|
|
44389
|
-
async function buildForOneSession(sessionId, events, adapters2) {
|
|
44413
|
+
async function buildForOneSession(sessionId, events, adapters2, onSlice) {
|
|
44414
|
+
onSlice?.(0, 0);
|
|
44390
44415
|
const sorted = [...events].sort((a, b) => a.ts.localeCompare(b.ts));
|
|
44391
44416
|
const turnSurfaces = sorted.map((e) => turnSurface(e));
|
|
44392
44417
|
const turnEmbeddings = [];
|
|
@@ -44447,7 +44472,9 @@ async function buildForOneSession(sessionId, events, adapters2) {
|
|
|
44447
44472
|
const segments = [];
|
|
44448
44473
|
let failed = 0;
|
|
44449
44474
|
let lastError = null;
|
|
44450
|
-
for (
|
|
44475
|
+
for (let mi = 0; mi < merged.length; mi++) {
|
|
44476
|
+
const slice = merged[mi];
|
|
44477
|
+
onSlice?.(mi + 1, merged.length);
|
|
44451
44478
|
try {
|
|
44452
44479
|
const seg = await summariseSlice(sessionId, slice, adapters2);
|
|
44453
44480
|
if (seg) segments.push(seg);
|
|
@@ -45297,27 +45324,15 @@ __export(pipeline_exports, {
|
|
|
45297
45324
|
buildSegments: () => buildSegments,
|
|
45298
45325
|
preflightSummariser: () => preflightSummariser
|
|
45299
45326
|
});
|
|
45300
|
-
async function probeOllama(baseUrl) {
|
|
45301
|
-
try {
|
|
45302
|
-
const ctrl = new AbortController();
|
|
45303
|
-
const t = setTimeout(() => ctrl.abort(), 500);
|
|
45304
|
-
const res = await fetch(`${baseUrl.replace(/\/+$/, "")}/api/tags`, {
|
|
45305
|
-
method: "GET",
|
|
45306
|
-
signal: ctrl.signal
|
|
45307
|
-
});
|
|
45308
|
-
clearTimeout(t);
|
|
45309
|
-
return res.ok;
|
|
45310
|
-
} catch {
|
|
45311
|
-
return false;
|
|
45312
|
-
}
|
|
45313
|
-
}
|
|
45314
45327
|
async function bundledAdapters() {
|
|
45315
45328
|
const llamaCfg = defaultLlamaConfig();
|
|
45316
45329
|
return {
|
|
45317
|
-
//
|
|
45318
|
-
//
|
|
45319
|
-
//
|
|
45320
|
-
//
|
|
45330
|
+
// transformers.js BGE-small embedder — the same model the server
|
|
45331
|
+
// uses, so segment vectors land in the same 384-dim space as
|
|
45332
|
+
// leaf-description vectors and cosine similarity is directly
|
|
45333
|
+
// meaningful. (This path used to ship vector-less with empty
|
|
45334
|
+
// arrays; hooking embeddings here gives proper segment-vs-leaf
|
|
45335
|
+
// matching at classify time.)
|
|
45321
45336
|
embed: createTransformersJsEmbedder(),
|
|
45322
45337
|
summarize: llamaSummarize(llamaCfg),
|
|
45323
45338
|
tokenize: (text) => Math.max(1, Math.ceil(text.length / 4)),
|
|
@@ -45334,38 +45349,12 @@ async function bundledAdapters() {
|
|
|
45334
45349
|
};
|
|
45335
45350
|
}
|
|
45336
45351
|
async function getAdapters() {
|
|
45337
|
-
if (adapters
|
|
45338
|
-
const ollamaCfg = defaultOllamaConfig();
|
|
45339
|
-
const ollamaUp = await probeOllama(ollamaCfg.baseUrl);
|
|
45340
|
-
probed = true;
|
|
45341
|
-
if (ollamaUp) {
|
|
45342
|
-
console.log(
|
|
45343
|
-
`[modelstat] ollama up at ${ollamaCfg.baseUrl} \u2014 using ${ollamaCfg.chatModel} for summarisation`
|
|
45344
|
-
);
|
|
45345
|
-
adapters = {
|
|
45346
|
-
// BGE-small via transformers.js — same model the server uses,
|
|
45347
|
-
// so segment vectors land in the same 384-dim space as
|
|
45348
|
-
// leaf-description vectors and cosine similarity is directly
|
|
45349
|
-
// meaningful. We do NOT use ollamaEmbed here because Ollama's
|
|
45350
|
-
// library doesn't host bge-small (404 on pull) and shipping
|
|
45351
|
-
// MiniLM via Ollama vs BGE-small server-side would break
|
|
45352
|
-
// cross-source similarity.
|
|
45353
|
-
embed: createTransformersJsEmbedder(),
|
|
45354
|
-
summarize: ollamaSummarize(ollamaCfg),
|
|
45355
|
-
tokenize: ollamaTokenize(),
|
|
45356
|
-
cognize: ollamaCognize(ollamaCfg),
|
|
45357
|
-
// Privacy filter — same OpenAI Privacy Filter model regardless
|
|
45358
|
-
// of which summariser/embedder runtime we ended up on. Factory
|
|
45359
|
-
// is async (dynamic-imports @huggingface/transformers).
|
|
45360
|
-
redact: await createPrivacyFilterRedactor()
|
|
45361
|
-
};
|
|
45362
|
-
return adapters;
|
|
45363
|
-
}
|
|
45352
|
+
if (adapters) return adapters;
|
|
45364
45353
|
try {
|
|
45365
45354
|
await import("node-llama-cpp");
|
|
45366
45355
|
} catch (err) {
|
|
45367
45356
|
throw new Error(
|
|
45368
|
-
`modelstat agent can't start:
|
|
45357
|
+
`modelstat agent can't start: the bundled summariser (node-llama-cpp) failed to load. Re-run \`modelstat connect\` (or \`npm i -g modelstat\`) so the native runtime is re-staged beside the bundle. Underlying error: ${err.message}`
|
|
45369
45358
|
);
|
|
45370
45359
|
}
|
|
45371
45360
|
console.log(
|
|
@@ -45374,8 +45363,8 @@ async function getAdapters() {
|
|
|
45374
45363
|
adapters = await bundledAdapters();
|
|
45375
45364
|
return adapters;
|
|
45376
45365
|
}
|
|
45377
|
-
async function buildSegments(events) {
|
|
45378
|
-
return buildSegmentsForSession(events, await getAdapters());
|
|
45366
|
+
async function buildSegments(events, onProgress) {
|
|
45367
|
+
return buildSegmentsForSession(events, await getAdapters(), onProgress);
|
|
45379
45368
|
}
|
|
45380
45369
|
async function preflightSummariser() {
|
|
45381
45370
|
const a = await getAdapters();
|
|
@@ -45390,7 +45379,7 @@ async function preflightSummariser() {
|
|
|
45390
45379
|
}
|
|
45391
45380
|
return out.length > 60 ? `${out.slice(0, 57)}\u2026` : out;
|
|
45392
45381
|
}
|
|
45393
|
-
var adapters
|
|
45382
|
+
var adapters;
|
|
45394
45383
|
var init_pipeline2 = __esm({
|
|
45395
45384
|
"src/pipeline.ts"() {
|
|
45396
45385
|
"use strict";
|
|
@@ -45398,7 +45387,6 @@ var init_pipeline2 = __esm({
|
|
|
45398
45387
|
init_node2();
|
|
45399
45388
|
init_privacy_filter();
|
|
45400
45389
|
adapters = null;
|
|
45401
|
-
probed = false;
|
|
45402
45390
|
}
|
|
45403
45391
|
});
|
|
45404
45392
|
|
|
@@ -45406,6 +45394,9 @@ var init_pipeline2 = __esm({
|
|
|
45406
45394
|
import { readdir, stat as stat2 } from "fs/promises";
|
|
45407
45395
|
import { homedir as homedir5 } from "os";
|
|
45408
45396
|
import { join as join4 } from "path";
|
|
45397
|
+
function withNonNullTokens(e) {
|
|
45398
|
+
return e.tokens ? e : { ...e, tokens: { ...ZERO_TOKENS } };
|
|
45399
|
+
}
|
|
45409
45400
|
async function scanAll(cb = {}) {
|
|
45410
45401
|
const deviceId = state.deviceId;
|
|
45411
45402
|
if (!deviceId) throw new Error("agent not enrolled \u2014 run `register` first");
|
|
@@ -45463,25 +45454,29 @@ async function scanAll(cb = {}) {
|
|
|
45463
45454
|
let filesUnchanged = 0;
|
|
45464
45455
|
let batchesUploaded = 0;
|
|
45465
45456
|
let eventsUploaded = 0;
|
|
45457
|
+
let segmentsUploaded = 0;
|
|
45466
45458
|
let buffer = [];
|
|
45467
45459
|
let pendingCursors = [];
|
|
45468
45460
|
async function flushBatch() {
|
|
45469
45461
|
if (!buffer.length) return;
|
|
45470
|
-
|
|
45471
|
-
const segments = await buildSegments(
|
|
45462
|
+
const events = buffer.map(withNonNullTokens);
|
|
45463
|
+
const segments = await buildSegments(events, cb.onProgress);
|
|
45472
45464
|
const batch = {
|
|
45473
45465
|
batch_id: batchId(),
|
|
45474
45466
|
device_id: deviceId,
|
|
45475
45467
|
agent_version: AGENT_VERSION,
|
|
45476
|
-
events
|
|
45468
|
+
events,
|
|
45477
45469
|
segments
|
|
45478
45470
|
};
|
|
45471
|
+
cb.onUpload?.({ events: events.length, segments: segments.length });
|
|
45479
45472
|
const res = await uploadBatch(batch);
|
|
45480
45473
|
batchesUploaded += 1;
|
|
45481
45474
|
eventsUploaded += res.accepted;
|
|
45475
|
+
segmentsUploaded += segments.length;
|
|
45482
45476
|
for (const pc of pendingCursors) state.setCursor(pc.path, pc.cs);
|
|
45483
45477
|
pendingCursors = [];
|
|
45484
45478
|
buffer = [];
|
|
45479
|
+
cb.onUploaded?.({ events: res.accepted, segments: segments.length });
|
|
45485
45480
|
}
|
|
45486
45481
|
for (let i = 0; i < jobs.length; i++) {
|
|
45487
45482
|
const job = jobs[i];
|
|
@@ -45507,9 +45502,9 @@ async function scanAll(cb = {}) {
|
|
|
45507
45502
|
}
|
|
45508
45503
|
}
|
|
45509
45504
|
await flushBatch();
|
|
45510
|
-
return { filesScanned, filesUnchanged, batchesUploaded, eventsUploaded };
|
|
45505
|
+
return { filesScanned, filesUnchanged, batchesUploaded, eventsUploaded, segmentsUploaded };
|
|
45511
45506
|
}
|
|
45512
|
-
var AGENT_VERSION, BATCH_MAX_EVENTS;
|
|
45507
|
+
var AGENT_VERSION, BATCH_MAX_EVENTS, ZERO_TOKENS;
|
|
45513
45508
|
var init_scan = __esm({
|
|
45514
45509
|
"src/scan.ts"() {
|
|
45515
45510
|
"use strict";
|
|
@@ -45518,8 +45513,15 @@ var init_scan = __esm({
|
|
|
45518
45513
|
init_pipeline2();
|
|
45519
45514
|
init_config2();
|
|
45520
45515
|
init_api();
|
|
45521
|
-
AGENT_VERSION = "agent-0.0.
|
|
45516
|
+
AGENT_VERSION = true ? "agent-0.0.42" : "agent-dev";
|
|
45522
45517
|
BATCH_MAX_EVENTS = 2e3;
|
|
45518
|
+
ZERO_TOKENS = {
|
|
45519
|
+
input: 0,
|
|
45520
|
+
output: 0,
|
|
45521
|
+
cache_creation: 0,
|
|
45522
|
+
cache_read: 0,
|
|
45523
|
+
reasoning: 0
|
|
45524
|
+
};
|
|
45523
45525
|
}
|
|
45524
45526
|
});
|
|
45525
45527
|
|
|
@@ -45529,7 +45531,7 @@ import {
|
|
|
45529
45531
|
existsSync as existsSync7,
|
|
45530
45532
|
mkdirSync as mkdirSync3,
|
|
45531
45533
|
openSync,
|
|
45532
|
-
readFileSync as
|
|
45534
|
+
readFileSync as readFileSync4,
|
|
45533
45535
|
renameSync as renameSync2,
|
|
45534
45536
|
unlinkSync as unlinkSync2,
|
|
45535
45537
|
writeFileSync as writeFileSync4,
|
|
@@ -45550,7 +45552,7 @@ function isProcessAlive(pid) {
|
|
|
45550
45552
|
}
|
|
45551
45553
|
function readLock() {
|
|
45552
45554
|
try {
|
|
45553
|
-
const raw =
|
|
45555
|
+
const raw = readFileSync4(LOCK_FILE, "utf8");
|
|
45554
45556
|
const obj = JSON.parse(raw);
|
|
45555
45557
|
if (typeof obj.pid !== "number") return null;
|
|
45556
45558
|
return {
|
|
@@ -45642,6 +45644,47 @@ var init_lock = __esm({
|
|
|
45642
45644
|
}
|
|
45643
45645
|
});
|
|
45644
45646
|
|
|
45647
|
+
// src/single-flight.ts
|
|
45648
|
+
function createCoalescingRunner(task) {
|
|
45649
|
+
let running = false;
|
|
45650
|
+
let next = null;
|
|
45651
|
+
let chain = Promise.resolve();
|
|
45652
|
+
function trigger(arg) {
|
|
45653
|
+
if (running) {
|
|
45654
|
+
next = { arg };
|
|
45655
|
+
return chain;
|
|
45656
|
+
}
|
|
45657
|
+
running = true;
|
|
45658
|
+
chain = (async () => {
|
|
45659
|
+
let cur = arg;
|
|
45660
|
+
try {
|
|
45661
|
+
for (; ; ) {
|
|
45662
|
+
try {
|
|
45663
|
+
await task(cur);
|
|
45664
|
+
} catch {
|
|
45665
|
+
}
|
|
45666
|
+
if (!next) break;
|
|
45667
|
+
cur = next.arg;
|
|
45668
|
+
next = null;
|
|
45669
|
+
}
|
|
45670
|
+
} finally {
|
|
45671
|
+
running = false;
|
|
45672
|
+
}
|
|
45673
|
+
})();
|
|
45674
|
+
return chain;
|
|
45675
|
+
}
|
|
45676
|
+
return {
|
|
45677
|
+
trigger,
|
|
45678
|
+
isRunning: () => running,
|
|
45679
|
+
isPending: () => next !== null
|
|
45680
|
+
};
|
|
45681
|
+
}
|
|
45682
|
+
var init_single_flight = __esm({
|
|
45683
|
+
"src/single-flight.ts"() {
|
|
45684
|
+
"use strict";
|
|
45685
|
+
}
|
|
45686
|
+
});
|
|
45687
|
+
|
|
45645
45688
|
// src/processing-version.ts
|
|
45646
45689
|
var processing_version_exports = {};
|
|
45647
45690
|
__export(processing_version_exports, {
|
|
@@ -47387,35 +47430,47 @@ __export(daemon_exports, {
|
|
|
47387
47430
|
bumpStat: () => bumpStat,
|
|
47388
47431
|
noteEventAt: () => noteEventAt,
|
|
47389
47432
|
runDaemon: () => runDaemon,
|
|
47433
|
+
setMessage: () => setMessage,
|
|
47390
47434
|
setPhase: () => setPhase,
|
|
47391
47435
|
setProgress: () => setProgress,
|
|
47392
|
-
setQueue: () => setQueue
|
|
47436
|
+
setQueue: () => setQueue,
|
|
47437
|
+
setStat: () => setStat
|
|
47393
47438
|
});
|
|
47394
47439
|
import { existsSync as existsSync8, statSync as statSync2 } from "fs";
|
|
47395
47440
|
function setPhase(phase, message) {
|
|
47396
47441
|
status.phase = phase;
|
|
47397
47442
|
status.message = message ?? null;
|
|
47443
|
+
scheduleLocalFlush();
|
|
47444
|
+
}
|
|
47445
|
+
function setMessage(message) {
|
|
47446
|
+
status.message = message;
|
|
47447
|
+
scheduleLocalFlush();
|
|
47398
47448
|
}
|
|
47399
47449
|
function setProgress(done, total) {
|
|
47400
47450
|
status.progressDone = done;
|
|
47401
47451
|
status.progressTotal = total;
|
|
47452
|
+
scheduleLocalFlush();
|
|
47402
47453
|
}
|
|
47403
47454
|
function setQueue(n) {
|
|
47404
47455
|
status.queueSize = n;
|
|
47456
|
+
scheduleLocalFlush();
|
|
47405
47457
|
}
|
|
47406
47458
|
function bumpStat(key, delta) {
|
|
47407
47459
|
const cur = Number(status.stats[key] ?? 0);
|
|
47408
47460
|
status.stats[key] = cur + delta;
|
|
47461
|
+
scheduleLocalFlush();
|
|
47462
|
+
}
|
|
47463
|
+
function setStat(key, value) {
|
|
47464
|
+
status.stats[key] = value;
|
|
47465
|
+
scheduleLocalFlush();
|
|
47409
47466
|
}
|
|
47410
47467
|
function noteEventAt(iso) {
|
|
47411
47468
|
status.lastEventAt = iso;
|
|
47469
|
+
scheduleLocalFlush();
|
|
47412
47470
|
}
|
|
47413
|
-
|
|
47414
|
-
|
|
47415
|
-
|
|
47416
|
-
if (!bearer || !deviceId) return;
|
|
47417
|
-
const body = {
|
|
47418
|
-
device_id: deviceId,
|
|
47471
|
+
function snapshotBody() {
|
|
47472
|
+
return {
|
|
47473
|
+
device_id: state.deviceId ?? null,
|
|
47419
47474
|
status: status.phase,
|
|
47420
47475
|
message: status.message,
|
|
47421
47476
|
progress_done: status.progressDone,
|
|
@@ -47425,6 +47480,27 @@ async function sendHeartbeat() {
|
|
|
47425
47480
|
last_event_at: status.lastEventAt,
|
|
47426
47481
|
agent_version: AGENT_VERSION2
|
|
47427
47482
|
};
|
|
47483
|
+
}
|
|
47484
|
+
function scheduleLocalFlush() {
|
|
47485
|
+
if (localFlushTimer) {
|
|
47486
|
+
localFlushPending = true;
|
|
47487
|
+
return;
|
|
47488
|
+
}
|
|
47489
|
+
writeLocalStatus(snapshotBody()).catch(() => void 0);
|
|
47490
|
+
localFlushTimer = setTimeout(() => {
|
|
47491
|
+
localFlushTimer = null;
|
|
47492
|
+
if (localFlushPending) {
|
|
47493
|
+
localFlushPending = false;
|
|
47494
|
+
scheduleLocalFlush();
|
|
47495
|
+
}
|
|
47496
|
+
}, LOCAL_FLUSH_THROTTLE_MS);
|
|
47497
|
+
localFlushTimer.unref();
|
|
47498
|
+
}
|
|
47499
|
+
async function sendHeartbeat() {
|
|
47500
|
+
const bearer = state.bearer;
|
|
47501
|
+
const deviceId = state.deviceId;
|
|
47502
|
+
if (!bearer || !deviceId) return;
|
|
47503
|
+
const body = { ...snapshotBody(), device_id: deviceId };
|
|
47428
47504
|
try {
|
|
47429
47505
|
const res = await (0, import_undici2.request)(`${state.apiUrl}/v1/agent/heartbeat`, {
|
|
47430
47506
|
method: "POST",
|
|
@@ -47482,13 +47558,29 @@ async function runScanCycle(reason) {
|
|
|
47482
47558
|
try {
|
|
47483
47559
|
const r = await scanAll({
|
|
47484
47560
|
onFile(path5, index, total) {
|
|
47485
|
-
setProgress(index, total);
|
|
47486
|
-
|
|
47561
|
+
setProgress(index + 1, total);
|
|
47562
|
+
setMessage(`Scanning ${index + 1}/${total}: ${basename3(path5)}`);
|
|
47487
47563
|
},
|
|
47488
|
-
|
|
47489
|
-
|
|
47490
|
-
|
|
47564
|
+
onProgress(p) {
|
|
47565
|
+
const sess = p.sessionTotal > 1 ? ` \xB7 session ${p.session}/${p.sessionTotal}` : "";
|
|
47566
|
+
if (p.segment === 0) {
|
|
47567
|
+
setPhase("processing", `Analyzing${sess}`);
|
|
47568
|
+
} else {
|
|
47569
|
+
setPhase(
|
|
47570
|
+
"processing",
|
|
47571
|
+
`Summarising segment ${p.segment}/${p.segmentTotal}${sess}`
|
|
47572
|
+
);
|
|
47573
|
+
}
|
|
47574
|
+
},
|
|
47575
|
+
onUpload({ segments }) {
|
|
47576
|
+
setPhase("uploading", `Uploading ${segments} segments`);
|
|
47577
|
+
setStat("segments_sending", segments);
|
|
47578
|
+
},
|
|
47579
|
+
onUploaded({ events, segments }) {
|
|
47580
|
+
bumpStat("events_uploaded", events);
|
|
47491
47581
|
bumpStat("batches_uploaded", 1);
|
|
47582
|
+
setStat("segments_sent", state.bumpSegmentsSent(segments));
|
|
47583
|
+
setStat("segments_sending", 0);
|
|
47492
47584
|
status.lastEventAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
47493
47585
|
}
|
|
47494
47586
|
});
|
|
@@ -47497,9 +47589,13 @@ async function runScanCycle(reason) {
|
|
|
47497
47589
|
setPhase("watching", "Waiting for new events");
|
|
47498
47590
|
setProgress(0, 0);
|
|
47499
47591
|
} catch (e) {
|
|
47592
|
+
setStat("segments_sending", 0);
|
|
47500
47593
|
setPhase("offline", `Upload failed: ${describeErrorWithCause(e)}`);
|
|
47501
47594
|
}
|
|
47502
47595
|
}
|
|
47596
|
+
function requestScan(reason) {
|
|
47597
|
+
return scanRunner.trigger(reason);
|
|
47598
|
+
}
|
|
47503
47599
|
function basename3(p) {
|
|
47504
47600
|
return p.split("/").pop() ?? p;
|
|
47505
47601
|
}
|
|
@@ -47527,6 +47623,7 @@ async function runDaemon(opts = {}) {
|
|
|
47527
47623
|
return;
|
|
47528
47624
|
}
|
|
47529
47625
|
setPhase("starting", "Booting");
|
|
47626
|
+
setStat("segments_sent", state.segmentsSent);
|
|
47530
47627
|
const hb = setInterval(() => void sendHeartbeat(), HEARTBEAT_INTERVAL_MS);
|
|
47531
47628
|
hb.unref();
|
|
47532
47629
|
void sendHeartbeat();
|
|
@@ -47547,7 +47644,7 @@ async function runDaemon(opts = {}) {
|
|
|
47547
47644
|
);
|
|
47548
47645
|
}
|
|
47549
47646
|
await runDiscovery();
|
|
47550
|
-
await
|
|
47647
|
+
await requestScan("startup");
|
|
47551
47648
|
const chokidar = (await Promise.resolve().then(() => (init_esm2(), esm_exports))).default;
|
|
47552
47649
|
const { homedir: homedir9, platform: platform5 } = await import("os");
|
|
47553
47650
|
const { join: join10 } = await import("path");
|
|
@@ -47576,7 +47673,7 @@ async function runDaemon(opts = {}) {
|
|
|
47576
47673
|
if (scanTimer) return;
|
|
47577
47674
|
scanTimer = setTimeout(() => {
|
|
47578
47675
|
scanTimer = null;
|
|
47579
|
-
void
|
|
47676
|
+
void requestScan(reason);
|
|
47580
47677
|
}, 1e3);
|
|
47581
47678
|
};
|
|
47582
47679
|
watcher.on("add", (p) => {
|
|
@@ -47584,9 +47681,9 @@ async function runDaemon(opts = {}) {
|
|
|
47584
47681
|
}).on("change", (p) => {
|
|
47585
47682
|
if (p.endsWith(".jsonl") || p.endsWith(".db")) scheduleScan(`change ${basename3(p)}`);
|
|
47586
47683
|
}).on("error", (e) => {
|
|
47587
|
-
|
|
47684
|
+
setMessage(`watcher error: ${e.message}`);
|
|
47588
47685
|
});
|
|
47589
|
-
const backstop = setInterval(() => void
|
|
47686
|
+
const backstop = setInterval(() => void requestScan("interval"), SCAN_INTERVAL_MS);
|
|
47590
47687
|
backstop.unref();
|
|
47591
47688
|
const discoveryTimer = setInterval(
|
|
47592
47689
|
() => void runDiscovery(),
|
|
@@ -47604,7 +47701,7 @@ async function runDaemon(opts = {}) {
|
|
|
47604
47701
|
await new Promise(() => {
|
|
47605
47702
|
});
|
|
47606
47703
|
}
|
|
47607
|
-
var import_undici2, AGENT_VERSION2, HEARTBEAT_INTERVAL_MS, SCAN_INTERVAL_MS, DISCOVERY_INTERVAL_MS, status, lastStatusPath;
|
|
47704
|
+
var import_undici2, AGENT_VERSION2, HEARTBEAT_INTERVAL_MS, SCAN_INTERVAL_MS, DISCOVERY_INTERVAL_MS, status, LOCAL_FLUSH_THROTTLE_MS, localFlushTimer, localFlushPending, lastStatusPath, scanRunner;
|
|
47608
47705
|
var init_daemon = __esm({
|
|
47609
47706
|
"src/daemon.ts"() {
|
|
47610
47707
|
"use strict";
|
|
@@ -47615,7 +47712,8 @@ var init_daemon = __esm({
|
|
|
47615
47712
|
init_config2();
|
|
47616
47713
|
init_lock();
|
|
47617
47714
|
init_scan();
|
|
47618
|
-
|
|
47715
|
+
init_single_flight();
|
|
47716
|
+
AGENT_VERSION2 = true ? "agent-0.0.42" : "agent-dev";
|
|
47619
47717
|
HEARTBEAT_INTERVAL_MS = 1e4;
|
|
47620
47718
|
SCAN_INTERVAL_MS = 5 * 60 * 1e3;
|
|
47621
47719
|
DISCOVERY_INTERVAL_MS = 6e4;
|
|
@@ -47628,7 +47726,11 @@ var init_daemon = __esm({
|
|
|
47628
47726
|
stats: {},
|
|
47629
47727
|
lastEventAt: null
|
|
47630
47728
|
};
|
|
47729
|
+
LOCAL_FLUSH_THROTTLE_MS = 400;
|
|
47730
|
+
localFlushTimer = null;
|
|
47731
|
+
localFlushPending = false;
|
|
47631
47732
|
lastStatusPath = null;
|
|
47733
|
+
scanRunner = createCoalescingRunner(runScanCycle);
|
|
47632
47734
|
}
|
|
47633
47735
|
});
|
|
47634
47736
|
|
|
@@ -47682,7 +47784,9 @@ async function safeScan(reason) {
|
|
|
47682
47784
|
console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}] scan (${reason})`);
|
|
47683
47785
|
const r = await scanAll();
|
|
47684
47786
|
if (r.batchesUploaded || r.eventsUploaded) {
|
|
47685
|
-
console.log(
|
|
47787
|
+
console.log(
|
|
47788
|
+
` \u2192 ${r.segmentsUploaded} segments \xB7 ${r.eventsUploaded} events in ${r.batchesUploaded} batches`
|
|
47789
|
+
);
|
|
47686
47790
|
}
|
|
47687
47791
|
} catch (e) {
|
|
47688
47792
|
console.warn(" ! scan failed:", e.message);
|
|
@@ -47742,9 +47846,12 @@ import {
|
|
|
47742
47846
|
copyFileSync,
|
|
47743
47847
|
existsSync as existsSync6,
|
|
47744
47848
|
mkdirSync as mkdirSync2,
|
|
47849
|
+
readFileSync as readFileSync3,
|
|
47850
|
+
realpathSync,
|
|
47745
47851
|
unlinkSync,
|
|
47746
47852
|
writeFileSync as writeFileSync3
|
|
47747
47853
|
} from "fs";
|
|
47854
|
+
import { createRequire } from "module";
|
|
47748
47855
|
import { homedir as homedir6, platform as platform2, userInfo } from "os";
|
|
47749
47856
|
import { dirname as dirname5, join as join5 } from "path";
|
|
47750
47857
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -47779,8 +47886,74 @@ function installBundle() {
|
|
|
47779
47886
|
);
|
|
47780
47887
|
}
|
|
47781
47888
|
copyFileSync(src, dest);
|
|
47889
|
+
installNativeRuntime(src);
|
|
47782
47890
|
return dest;
|
|
47783
47891
|
}
|
|
47892
|
+
function setupRuntime() {
|
|
47893
|
+
return installBundle();
|
|
47894
|
+
}
|
|
47895
|
+
var NODE_LLAMA_CPP_FALLBACK_VERSION = "3.18.1";
|
|
47896
|
+
function sourceLlamaVersion(sourceCli) {
|
|
47897
|
+
try {
|
|
47898
|
+
const req = createRequire(sourceCli);
|
|
47899
|
+
let d = dirname5(realpathSync(req.resolve("node-llama-cpp")));
|
|
47900
|
+
for (let i = 0; i < 10; i++) {
|
|
47901
|
+
const pj = join5(d, "package.json");
|
|
47902
|
+
if (existsSync6(pj)) {
|
|
47903
|
+
const p = JSON.parse(readFileSync3(pj, "utf8"));
|
|
47904
|
+
if (p.name === "node-llama-cpp" && p.version) return p.version;
|
|
47905
|
+
}
|
|
47906
|
+
const up = dirname5(d);
|
|
47907
|
+
if (up === d) break;
|
|
47908
|
+
d = up;
|
|
47909
|
+
}
|
|
47910
|
+
} catch {
|
|
47911
|
+
}
|
|
47912
|
+
return null;
|
|
47913
|
+
}
|
|
47914
|
+
function installNativeRuntime(sourceCli) {
|
|
47915
|
+
const version = sourceLlamaVersion(sourceCli) ?? NODE_LLAMA_CPP_FALLBACK_VERSION;
|
|
47916
|
+
const dest = binDir();
|
|
47917
|
+
try {
|
|
47918
|
+
const have = JSON.parse(
|
|
47919
|
+
readFileSync3(
|
|
47920
|
+
join5(dest, "node_modules", "node-llama-cpp", "package.json"),
|
|
47921
|
+
"utf8"
|
|
47922
|
+
)
|
|
47923
|
+
);
|
|
47924
|
+
if (have.version === version) return [`node-llama-cpp@${version} (cached)`];
|
|
47925
|
+
} catch {
|
|
47926
|
+
}
|
|
47927
|
+
mkdirSync2(dest, { recursive: true });
|
|
47928
|
+
const childEnv = { ...process.env };
|
|
47929
|
+
delete childEnv.npm_config_global;
|
|
47930
|
+
delete childEnv.npm_config_prefix;
|
|
47931
|
+
const r = spawnSync(
|
|
47932
|
+
"npm",
|
|
47933
|
+
[
|
|
47934
|
+
"install",
|
|
47935
|
+
"--prefix",
|
|
47936
|
+
dest,
|
|
47937
|
+
"--global=false",
|
|
47938
|
+
"--no-save",
|
|
47939
|
+
"--omit=dev",
|
|
47940
|
+
"--no-audit",
|
|
47941
|
+
"--no-fund",
|
|
47942
|
+
"--loglevel=error",
|
|
47943
|
+
`node-llama-cpp@${version}`
|
|
47944
|
+
],
|
|
47945
|
+
{ encoding: "utf8", stdio: "pipe", env: childEnv }
|
|
47946
|
+
);
|
|
47947
|
+
if (r.status !== 0) {
|
|
47948
|
+
process.stderr.write(
|
|
47949
|
+
`[modelstat] couldn't stage the bundled summariser runtime via npm (node-llama-cpp@${version}); the daemon's summariser preflight will fail until this is resolved.
|
|
47950
|
+
${(r.stderr || r.stdout || "").trim()}
|
|
47951
|
+
`
|
|
47952
|
+
);
|
|
47953
|
+
return [];
|
|
47954
|
+
}
|
|
47955
|
+
return [`node-llama-cpp@${version}`];
|
|
47956
|
+
}
|
|
47784
47957
|
function nodeBinary() {
|
|
47785
47958
|
return process.execPath;
|
|
47786
47959
|
}
|
|
@@ -48050,7 +48223,7 @@ function tryOpenBrowser(url) {
|
|
|
48050
48223
|
return false;
|
|
48051
48224
|
}
|
|
48052
48225
|
}
|
|
48053
|
-
var AGENT_VERSION3 = "agent-0.0.
|
|
48226
|
+
var AGENT_VERSION3 = true ? "agent-0.0.42" : "agent-dev";
|
|
48054
48227
|
function osFamily() {
|
|
48055
48228
|
const p = platform4();
|
|
48056
48229
|
if (p === "darwin") return "macos";
|
|
@@ -48376,7 +48549,7 @@ async function cmdScan() {
|
|
|
48376
48549
|
const r = await scanAll();
|
|
48377
48550
|
console.log();
|
|
48378
48551
|
console.log(
|
|
48379
|
-
`Done: ${r.filesScanned} files scanned, ${r.filesUnchanged} unchanged, ${r.batchesUploaded} batches, ${r.eventsUploaded} events uploaded`
|
|
48552
|
+
`Done: ${r.filesScanned} files scanned, ${r.filesUnchanged} unchanged, ${r.batchesUploaded} batches, ${r.segmentsUploaded} segments, ${r.eventsUploaded} events uploaded`
|
|
48380
48553
|
);
|
|
48381
48554
|
}
|
|
48382
48555
|
async function cmdRescan() {
|
|
@@ -48605,6 +48778,11 @@ async function main() {
|
|
|
48605
48778
|
case "_daemon":
|
|
48606
48779
|
case "start":
|
|
48607
48780
|
return cmdStart(rest);
|
|
48781
|
+
case "_setup-runtime": {
|
|
48782
|
+
const dest = setupRuntime();
|
|
48783
|
+
console.log(`\u2713 runtime staged at ${dest}`);
|
|
48784
|
+
return;
|
|
48785
|
+
}
|
|
48608
48786
|
// ── Diagnostics / dev one-shots ────────────────────────────
|
|
48609
48787
|
case "status":
|
|
48610
48788
|
return cmdStatus();
|