omnius 1.0.149 → 1.0.150

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/index.js CHANGED
@@ -11820,6 +11820,99 @@ async function _ensureHelia() {
11820
11820
  var _natsConn = null;
11821
11821
  var _natsCodec = null;
11822
11822
  var _tokensByRequest = {};
11823
+ var _sponsorLimits = null;
11824
+ var _sponsorActiveRequests = 0;
11825
+ var _sponsorRequestWindow = [];
11826
+ var _sponsorDailyTokensUsed = 0;
11827
+ var _sponsorDailyResetAt = Date.now() + 86400000;
11828
+ var _sponsorBlockedRequests = 0;
11829
+ var _sponsorTokenRateSamples = [];
11830
+
11831
+ function _sponsorPrune(now) {
11832
+ while (_sponsorRequestWindow.length > 0 && _sponsorRequestWindow[0] < now - 60000) _sponsorRequestWindow.shift();
11833
+ while (_sponsorTokenRateSamples.length > 0 && _sponsorTokenRateSamples[0].at < now - 10000) _sponsorTokenRateSamples.shift();
11834
+ if (_sponsorDailyResetAt <= now) {
11835
+ _sponsorDailyTokensUsed = 0;
11836
+ _sponsorDailyResetAt = now + 86400000;
11837
+ }
11838
+ }
11839
+
11840
+ function _sponsorTokenRate(now) {
11841
+ _sponsorPrune(now || Date.now());
11842
+ if (_sponsorTokenRateSamples.length === 0) return 0;
11843
+ var tokens = 0;
11844
+ for (var i = 0; i < _sponsorTokenRateSamples.length; i++) tokens += _sponsorTokenRateSamples[i].tokens || 0;
11845
+ var spanMs = Math.max(1000, (now || Date.now()) - _sponsorTokenRateSamples[0].at);
11846
+ return Math.round((tokens / (spanMs / 1000)) * 10) / 10;
11847
+ }
11848
+
11849
+ function _sponsorRecordTokenRate(tokens) {
11850
+ var n = Number(tokens) || 0;
11851
+ if (n <= 0) return _sponsorTokenRate(Date.now());
11852
+ var now = Date.now();
11853
+ _sponsorTokenRateSamples.push({ at: now, tokens: Math.floor(n) });
11854
+ return _sponsorTokenRate(now);
11855
+ }
11856
+
11857
+ function _sponsorEstimateTokens(text) {
11858
+ var len = String(text || '').length;
11859
+ return len > 0 ? Math.max(1, Math.ceil(len / 4)) : 0;
11860
+ }
11861
+
11862
+ function _sponsorAdmit(model) {
11863
+ if (!_sponsorLimits) return { ok: true };
11864
+ var now = Date.now();
11865
+ _sponsorPrune(now);
11866
+ if (_sponsorLimits.maxConcurrent <= 0 || _sponsorLimits.maxRequestsPerMinute <= 0 || _sponsorLimits.maxTokensPerDay <= 0) {
11867
+ _sponsorBlockedRequests++;
11868
+ return { ok: false, reason: 'Sponsored endpoint is paused or has no quota configured.' };
11869
+ }
11870
+ if (_sponsorLimits.allowedModels !== 'all' && _sponsorLimits.allowedModels.indexOf(model) === -1) {
11871
+ _sponsorBlockedRequests++;
11872
+ return { ok: false, reason: 'Model not allowed: ' + model };
11873
+ }
11874
+ if (_sponsorActiveRequests >= _sponsorLimits.maxConcurrent) {
11875
+ _sponsorBlockedRequests++;
11876
+ return { ok: false, reason: 'Too many concurrent requests (' + _sponsorActiveRequests + '/' + _sponsorLimits.maxConcurrent + '). Try again shortly.' };
11877
+ }
11878
+ if (_sponsorRequestWindow.length >= _sponsorLimits.maxRequestsPerMinute) {
11879
+ _sponsorBlockedRequests++;
11880
+ return { ok: false, reason: 'Rate limited (' + _sponsorLimits.maxRequestsPerMinute + ' req/min).' };
11881
+ }
11882
+ if (_sponsorDailyTokensUsed >= _sponsorLimits.maxTokensPerDay) {
11883
+ _sponsorBlockedRequests++;
11884
+ return { ok: false, reason: 'Daily token budget exhausted.' };
11885
+ }
11886
+ _sponsorActiveRequests++;
11887
+ _sponsorRequestWindow.push(now);
11888
+ return { ok: true };
11889
+ }
11890
+
11891
+ function _sponsorRelease() {
11892
+ if (_sponsorActiveRequests > 0) _sponsorActiveRequests--;
11893
+ }
11894
+
11895
+ function _sponsorRecordUsage(inputTokens, outputTokens, includeRate) {
11896
+ var input = Math.max(0, Math.floor(Number(inputTokens) || 0));
11897
+ var output = Math.max(0, Math.floor(Number(outputTokens) || 0));
11898
+ _sponsorPrune(Date.now());
11899
+ _sponsorDailyTokensUsed += input + output;
11900
+ if (includeRate !== false) _sponsorRecordTokenRate(output);
11901
+ }
11902
+
11903
+ function _sponsorGatewaySnapshot() {
11904
+ var now = Date.now();
11905
+ _sponsorPrune(now);
11906
+ return {
11907
+ activeConnections: _sponsorActiveRequests,
11908
+ requestsInWindow: _sponsorRequestWindow.length,
11909
+ dailyTokensUsed: _sponsorDailyTokensUsed,
11910
+ dailyResetAt: _sponsorDailyResetAt,
11911
+ blockedRequests: _sponsorBlockedRequests,
11912
+ tokensPerSecond: _sponsorTokenRate(now),
11913
+ limits: _sponsorLimits,
11914
+ };
11915
+ }
11823
11916
 
11824
11917
  // ── Nexus voice subsystem (PCM + ASR) ─────────────────────────────────
11825
11918
  // Subscribes to nexus.rooms.audio, filters by the rooms this daemon has
@@ -12032,10 +12125,22 @@ async function _collectSysMetrics() {
12032
12125
  var totalMem = os.totalmem();
12033
12126
  var freeMem = os.freemem();
12034
12127
  var usedMem = totalMem - freeMem;
12035
- var cpuModel = '';
12036
- try { var cpuArr = os.cpus(); if (cpuArr.length > 0) cpuModel = cpuArr[0].model || ''; } catch {}
12037
- var gpuInfo = { available: false, name: '', utilization: 0, vramUsedMB: 0, vramTotalMB: 0, vramUtilization: 0 };
12038
- try {
12128
+ var cpuModel = '';
12129
+ try { var cpuArr = os.cpus(); if (cpuArr.length > 0) cpuModel = cpuArr[0].model || ''; } catch {}
12130
+ var gpuInfo = { available: false, name: '', utilization: 0, vramUsedMB: 0, vramTotalMB: 0, vramUtilization: 0 };
12131
+ var diskInfo = { path: process.cwd(), totalGB: 0, freeGB: 0, usedGB: 0, utilization: -1 };
12132
+ try {
12133
+ var fs = await import('node:fs');
12134
+ var st = fs.statfsSync(process.cwd());
12135
+ var totalBytes = Number(st.blocks) * Number(st.bsize);
12136
+ var freeBytes = Number(st.bavail) * Number(st.bsize);
12137
+ var usedBytes = Math.max(0, totalBytes - freeBytes);
12138
+ diskInfo.totalGB = Math.round((totalBytes / (1024*1024*1024)) * 10) / 10;
12139
+ diskInfo.freeGB = Math.round((freeBytes / (1024*1024*1024)) * 10) / 10;
12140
+ diskInfo.usedGB = Math.round((usedBytes / (1024*1024*1024)) * 10) / 10;
12141
+ diskInfo.utilization = totalBytes > 0 ? Math.round((usedBytes / totalBytes) * 100) : -1;
12142
+ } catch {}
12143
+ try {
12039
12144
  var cp = await import('node:child_process');
12040
12145
  var smiOut = cp.execSync('nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null', { encoding: 'utf8', timeout: 3000 });
12041
12146
  var smiLine = smiOut.trim().split('\\n')[0];
@@ -12050,9 +12155,10 @@ async function _collectSysMetrics() {
12050
12155
  }
12051
12156
  } catch {}
12052
12157
  _sysMetricsCache = {
12053
- cpu: { utilization: Math.min(100, Math.round((loads[0] / cores) * 100)), cores: cores, model: cpuModel },
12054
- memory: { utilization: Math.round((usedMem / totalMem) * 100), totalGB: Math.round((totalMem / (1024*1024*1024)) * 10) / 10, usedGB: Math.round((usedMem / (1024*1024*1024)) * 10) / 10 },
12055
- gpu: gpuInfo,
12158
+ cpu: { utilization: Math.min(100, Math.round((loads[0] / cores) * 100)), cores: cores, model: cpuModel },
12159
+ memory: { utilization: Math.round((usedMem / totalMem) * 100), totalGB: Math.round((totalMem / (1024*1024*1024)) * 10) / 10, usedGB: Math.round((usedMem / (1024*1024*1024)) * 10) / 10 },
12160
+ disk: diskInfo,
12161
+ gpu: gpuInfo,
12056
12162
  timestamp: new Date().toISOString(),
12057
12163
  };
12058
12164
  _sysMetricsCacheTs = now;
@@ -12235,7 +12341,9 @@ async function handleCmd(cmd) {
12235
12341
  });
12236
12342
  }
12237
12343
  } catch {}
12238
- var sponsorData = {
12344
+ var sponsorLimitsArg = {};
12345
+ try { sponsorLimitsArg = args.limits ? JSON.parse(args.limits) : {}; } catch {}
12346
+ var sponsorData = {
12239
12347
  type: 'sponsor.announce',
12240
12348
  peerId: (connected ? nexus.peerId : 'unknown') || 'unknown',
12241
12349
  libp2pPeerId: (connected ? nexus.peerId : '') || '',
@@ -12244,10 +12352,11 @@ async function handleCmd(cmd) {
12244
12352
  modelDetails: _saModelDetails, // NX-07: per-model capacity
12245
12353
  tunnelUrl: args.tunnel_url || null,
12246
12354
  authKey: args.auth_key || '',
12247
- limits: {
12248
- maxRequestsPerMinute: parseInt(args.rpm || '60', 10),
12249
- maxTokensPerDay: parseInt(args.tpd || '100000', 10),
12250
- },
12355
+ limits: {
12356
+ maxRequestsPerMinute: parseInt(args.rpm || sponsorLimitsArg.maxRequestsPerMinute || '60', 10),
12357
+ maxTokensPerDay: parseInt(args.tpd || sponsorLimitsArg.maxTokensPerDay || '100000', 10),
12358
+ maxConcurrent: parseInt(args.max_concurrent || sponsorLimitsArg.maxConcurrent || '1', 10),
12359
+ },
12251
12360
  banner: args.banner || null,
12252
12361
  message: args.message || '',
12253
12362
  linkUrl: args.link_url || '',
@@ -12262,13 +12371,14 @@ async function handleCmd(cmd) {
12262
12371
 
12263
12372
  // Persist to KV-backed sponsor directory (omnius.nexus worker)
12264
12373
  try {
12265
- var kvResp = await fetch('https://omnius.nexus/api/v1/sponsors', {
12266
- method: 'POST',
12267
- headers: { 'Content-Type': 'application/json' },
12268
- body: JSON.stringify(sponsorData),
12269
- });
12270
- var kvResult = await kvResp.json();
12271
- dlog('sponsor_announce: KV persist ' + (kvResult.persisted ? 'OK' : 'skipped: ' + kvResult.reason));
12374
+ var kvResp = await fetch('https://omnius.nexus/api/v1/sponsors', {
12375
+ method: 'POST',
12376
+ headers: { 'Content-Type': 'application/json' },
12377
+ body: JSON.stringify(sponsorData),
12378
+ });
12379
+ var kvText = await kvResp.text();
12380
+ var kvResult = kvText.trim() ? JSON.parse(kvText) : { persisted: false, reason: 'empty directory response' };
12381
+ dlog('sponsor_announce: KV persist ' + (kvResult.persisted ? 'OK' : 'skipped: ' + kvResult.reason));
12272
12382
  } catch (kvErr) {
12273
12383
  dlog('sponsor_announce: KV persist failed: ' + (kvErr.message || kvErr));
12274
12384
  }
@@ -12388,11 +12498,12 @@ async function handleCmd(cmd) {
12388
12498
 
12389
12499
  // ── Source 1: KV-backed persistent directory (MOST RELIABLE) ──
12390
12500
  // Query the omnius.nexus worker for persisted sponsor listings
12391
- try {
12392
- var kvResp = await fetch('https://omnius.nexus/api/v1/sponsors', { signal: AbortSignal.timeout(5000) });
12393
- if (kvResp.ok) {
12394
- var kvData = await kvResp.json();
12395
- var kvSponsors = kvData.sponsors || [];
12501
+ try {
12502
+ var kvResp = await fetch('https://omnius.nexus/api/v1/sponsors', { signal: AbortSignal.timeout(5000) });
12503
+ if (kvResp.ok) {
12504
+ var kvText = await kvResp.text();
12505
+ var kvData = kvText.trim() ? JSON.parse(kvText) : { sponsors: [] };
12506
+ var kvSponsors = kvData.sponsors || [];
12396
12507
  for (var ki = 0; ki < kvSponsors.length; ki++) {
12397
12508
  var kvSp = kvSponsors[ki];
12398
12509
  if (kvSp.status === 'active') {
@@ -13433,6 +13544,28 @@ async function handleCmd(cmd) {
13433
13544
  dlog('expose: auth key configured (' + exposeAuthKey.length + ' chars)');
13434
13545
  }
13435
13546
 
13547
+ var sponsorMaxConcurrent = parseInt(args.max_concurrent || '0', 10);
13548
+ var sponsorMaxRequestsPerMinute = parseInt(args.max_requests_per_minute || '0', 10);
13549
+ var sponsorMaxTokensPerDay = parseInt(args.max_tokens_per_day || '0', 10);
13550
+ var sponsorAllowedModelsArg = args.allowed_models || '';
13551
+ if (sponsorMaxConcurrent > 0 || sponsorMaxRequestsPerMinute > 0 || sponsorMaxTokensPerDay > 0) {
13552
+ var sponsorDailyUsed = parseInt(args.daily_tokens_used || '0', 10);
13553
+ var sponsorDailyResetAt = parseInt(args.daily_tokens_reset_at || '0', 10);
13554
+ _sponsorDailyTokensUsed = Number.isFinite(sponsorDailyUsed) && sponsorDailyUsed > 0 ? sponsorDailyUsed : 0;
13555
+ _sponsorDailyResetAt = Number.isFinite(sponsorDailyResetAt) && sponsorDailyResetAt > Date.now() ? sponsorDailyResetAt : Date.now() + 86400000;
13556
+ _sponsorLimits = {
13557
+ maxConcurrent: sponsorMaxConcurrent > 0 ? sponsorMaxConcurrent : 1,
13558
+ maxRequestsPerMinute: sponsorMaxRequestsPerMinute > 0 ? sponsorMaxRequestsPerMinute : 1,
13559
+ maxTokensPerDay: sponsorMaxTokensPerDay > 0 ? sponsorMaxTokensPerDay : 1,
13560
+ allowedModels: sponsorAllowedModelsArg && sponsorAllowedModelsArg !== 'all'
13561
+ ? sponsorAllowedModelsArg.split(',').filter(Boolean)
13562
+ : 'all',
13563
+ };
13564
+ dlog('expose: sponsor limits active concurrent=' + _sponsorLimits.maxConcurrent + ' rpm=' + _sponsorLimits.maxRequestsPerMinute + ' tpd=' + _sponsorLimits.maxTokensPerDay);
13565
+ } else {
13566
+ _sponsorLimits = null;
13567
+ }
13568
+
13436
13569
  // Passthrough mode: forward from a remote /endpoint (Chutes, Groq, etc.)
13437
13570
  var isPassthrough = args.passthrough === 'true';
13438
13571
  var endpointAuth = args.endpoint_auth || '';
@@ -13500,6 +13633,11 @@ async function handleCmd(cmd) {
13500
13633
  }
13501
13634
  }
13502
13635
 
13636
+ if (_sponsorLimits && _sponsorLimits.allowedModels !== 'all') {
13637
+ models = models.filter(function(m) { return _sponsorLimits.allowedModels.indexOf(m.name) !== -1; });
13638
+ dlog('expose: sponsor allowlist filtered models to ' + models.length);
13639
+ }
13640
+
13503
13641
  if (models.length === 0) {
13504
13642
  writeResp(id, { ok: false, output: isPassthrough ? 'No models found on upstream endpoint.' : 'No models found on Ollama. Pull a model first.' });
13505
13643
  return;
@@ -13646,12 +13784,46 @@ async function handleCmd(cmd) {
13646
13784
  dlog('expose: auth OK for ' + capName);
13647
13785
  }
13648
13786
 
13649
- // Forward to Ollama — supports both flat prompt and structured messages
13650
- try {
13651
- var parsedReq = null;
13652
- try { parsedReq = JSON.parse(prompt); } catch (pe) { dlog('expose: JSON parse error: ' + (pe.message || pe)); }
13653
-
13654
- var genResp, genData, output, inputTokens, outputTokens, responsePayload;
13787
+ // Forward to Ollama — supports both flat prompt and structured messages
13788
+ var sponsorAdmissionOpen = false;
13789
+ try {
13790
+ var parsedReq = null;
13791
+ try { parsedReq = JSON.parse(prompt); } catch (pe) { dlog('expose: JSON parse error: ' + (pe.message || pe)); }
13792
+
13793
+ var sponsorAdmission = _sponsorAdmit(model.name);
13794
+ if (!sponsorAdmission.ok) {
13795
+ dlog('expose: sponsor limit rejected ' + capName + ' from ' + (request.from || 'unknown') + ': ' + sponsorAdmission.reason);
13796
+ await swrite({
13797
+ type: 'invoke.event', version: 1,
13798
+ requestId: request.requestId, seq: 0,
13799
+ event: 'error', data: sponsorAdmission.reason,
13800
+ });
13801
+ await swrite({
13802
+ type: 'invoke.done', version: 1,
13803
+ requestId: request.requestId,
13804
+ usage: { inputBytes: 0, outputBytes: 0 },
13805
+ });
13806
+ try {
13807
+ appendFileSync(meteringFile, JSON.stringify({
13808
+ timestamp: Date.now(),
13809
+ peerId: request.from || 'unknown',
13810
+ service: capName,
13811
+ capability: capName,
13812
+ model: model.name,
13813
+ direction: 'inbound',
13814
+ blocked: true,
13815
+ reason: sponsorAdmission.reason,
13816
+ inputTokens: 0,
13817
+ outputTokens: 0,
13818
+ tokens: 0,
13819
+ }) + '\\n');
13820
+ } catch {}
13821
+ try { stream.close(); } catch {}
13822
+ return;
13823
+ }
13824
+ sponsorAdmissionOpen = true;
13825
+
13826
+ var genResp, genData, output, inputTokens, outputTokens, responsePayload;
13655
13827
 
13656
13828
  // Detect if requester wants streaming (outputMode from invoke.open)
13657
13829
  var wantsStream = request.outputMode === 'stream';
@@ -13708,9 +13880,10 @@ async function handleCmd(cmd) {
13708
13880
  var sseObj = JSON.parse(sseData);
13709
13881
  var sseDelta = (sseObj.choices && sseObj.choices[0] && sseObj.choices[0].delta) || {};
13710
13882
  var sseToken = sseDelta.content || '';
13711
- if (sseToken) {
13712
- sseContent += sseToken;
13713
- await swrite({
13883
+ if (sseToken) {
13884
+ sseContent += sseToken;
13885
+ _sponsorRecordTokenRate(_sponsorEstimateTokens(sseToken));
13886
+ await swrite({
13714
13887
  type: 'invoke.event', version: 1,
13715
13888
  requestId: request.requestId, seq: sseSeq++,
13716
13889
  event: 'token', data: sseToken,
@@ -13839,12 +14012,14 @@ async function handleCmd(cmd) {
13839
14012
 
13840
14013
  // Attach system metrics to response — clients get CPU/GPU/RAM
13841
14014
  // for free without a separate invoke_capability round-trip
13842
- try {
13843
- var _sm = await _collectSysMetrics();
13844
- if (_sm) responsePayload.system = _sm;
13845
- } catch {}
14015
+ try {
14016
+ var _sm = await _collectSysMetrics();
14017
+ if (_sm) responsePayload.system = Object.assign({}, _sm, { gateway: _sponsorGatewaySnapshot() });
14018
+ } catch {}
13846
14019
 
13847
- // Stream result back
14020
+ _sponsorRecordUsage(inputTokens, outputTokens, !wantsStream);
14021
+
14022
+ // Stream result back
13848
14023
  await swrite({
13849
14024
  type: 'invoke.event', version: 1,
13850
14025
  requestId: request.requestId, seq: 0,
@@ -13882,10 +14057,12 @@ async function handleCmd(cmd) {
13882
14057
  await swrite({
13883
14058
  type: 'invoke.done', version: 1,
13884
14059
  requestId: request.requestId,
13885
- usage: { inputBytes: 0, outputBytes: 0 },
13886
- });
13887
- }
13888
- try { stream.close(); } catch {}
14060
+ usage: { inputBytes: 0, outputBytes: 0 },
14061
+ });
14062
+ } finally {
14063
+ if (sponsorAdmissionOpen) _sponsorRelease();
14064
+ }
14065
+ try { stream.close(); } catch {}
13889
14066
  }, capOpts);
13890
14067
  }
13891
14068
  }
@@ -13948,10 +14125,22 @@ async function handleCmd(cmd) {
13948
14125
  var os = await import('node:os');
13949
14126
  var loads = os.loadavg();
13950
14127
  var cores = os.cpus().length;
13951
- var totalMem = os.totalmem();
13952
- var freeMem = os.freemem();
13953
- var usedMem = totalMem - freeMem;
13954
- var gpuInfo = { available: false, name: '', utilization: 0, vramUsedMB: 0, vramTotalMB: 0, vramUtilization: 0 };
14128
+ var totalMem = os.totalmem();
14129
+ var freeMem = os.freemem();
14130
+ var usedMem = totalMem - freeMem;
14131
+ var gpuInfo = { available: false, name: '', utilization: 0, vramUsedMB: 0, vramTotalMB: 0, vramUtilization: 0 };
14132
+ var diskInfo = { path: process.cwd(), totalGB: 0, freeGB: 0, usedGB: 0, utilization: -1 };
14133
+ try {
14134
+ var fs = await import('node:fs');
14135
+ var st = fs.statfsSync(process.cwd());
14136
+ var totalBytes = Number(st.blocks) * Number(st.bsize);
14137
+ var freeBytes = Number(st.bavail) * Number(st.bsize);
14138
+ var usedBytes = Math.max(0, totalBytes - freeBytes);
14139
+ diskInfo.totalGB = Math.round((totalBytes / (1024*1024*1024)) * 10) / 10;
14140
+ diskInfo.freeGB = Math.round((freeBytes / (1024*1024*1024)) * 10) / 10;
14141
+ diskInfo.usedGB = Math.round((usedBytes / (1024*1024*1024)) * 10) / 10;
14142
+ diskInfo.utilization = totalBytes > 0 ? Math.round((usedBytes / totalBytes) * 100) : -1;
14143
+ } catch {}
13955
14144
  try {
13956
14145
  var cp = await import('node:child_process');
13957
14146
  var smiOut = cp.execSync('nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null', { encoding: 'utf8', timeout: 3000 });
@@ -13968,12 +14157,14 @@ async function handleCmd(cmd) {
13968
14157
  } catch (ge) { /* no GPU */ }
13969
14158
  var cpuModel = '';
13970
14159
  try { var cpuInfoArr = os.cpus(); if (cpuInfoArr.length > 0) cpuModel = cpuInfoArr[0].model || ''; } catch {}
13971
- var metricsPayload = {
13972
- cpu: { utilization: Math.min(100, Math.round((loads[0] / cores) * 100)), cores: cores, model: cpuModel },
13973
- memory: { utilization: Math.round((usedMem / totalMem) * 100), totalGB: Math.round((totalMem / (1024*1024*1024)) * 10) / 10, usedGB: Math.round((usedMem / (1024*1024*1024)) * 10) / 10 },
13974
- gpu: gpuInfo,
13975
- timestamp: new Date().toISOString(),
13976
- };
14160
+ var metricsPayload = {
14161
+ cpu: { utilization: Math.min(100, Math.round((loads[0] / cores) * 100)), cores: cores, model: cpuModel },
14162
+ memory: { utilization: Math.round((usedMem / totalMem) * 100), totalGB: Math.round((totalMem / (1024*1024*1024)) * 10) / 10, usedGB: Math.round((usedMem / (1024*1024*1024)) * 10) / 10 },
14163
+ disk: diskInfo,
14164
+ gpu: gpuInfo,
14165
+ gateway: _sponsorGatewaySnapshot(),
14166
+ timestamp: new Date().toISOString(),
14167
+ };
13977
14168
  await smWrite({ type: 'invoke.event', version: 1, requestId: request.requestId, seq: 0, event: 'result', data: JSON.stringify(metricsPayload) });
13978
14169
  await smWrite({ type: 'invoke.done', version: 1, requestId: request.requestId, usage: { inputBytes: 0, outputBytes: JSON.stringify(metricsPayload).length } });
13979
14170
  } catch (me) {
@@ -18106,7 +18297,8 @@ ${earlyError ? "\n" + earlyError : ""}${earlyOutput ? "\n" + earlyOutput : ""}`;
18106
18297
  model,
18107
18298
  target_peer: args.target_peer,
18108
18299
  temperature: args.temperature,
18109
- max_tokens: args.max_tokens
18300
+ max_tokens: args.max_tokens,
18301
+ auth_key: args.auth_key
18110
18302
  };
18111
18303
  if (args.messages) {
18112
18304
  daemonArgs.messages = args.messages;
@@ -571791,6 +571983,95 @@ function safeNonNegativeInt(value2) {
571791
571983
  const n2 = Number(value2);
571792
571984
  return Number.isFinite(n2) && n2 > 0 ? Math.floor(n2) : 0;
571793
571985
  }
571986
+ function currentTokenRate(samples, now = Date.now()) {
571987
+ while (samples.length > 0 && samples[0].at < now - 1e4) samples.shift();
571988
+ if (samples.length === 0) return 0;
571989
+ const tokens = samples.reduce((sum, sample) => sum + sample.tokens, 0);
571990
+ const spanMs = Math.max(1e3, now - samples[0].at);
571991
+ return Math.round(tokens / (spanMs / 1e3) * 10) / 10;
571992
+ }
571993
+ function recordTokenRate(samples, tokens, now = Date.now()) {
571994
+ const count = safeNonNegativeInt(tokens);
571995
+ if (count > 0) samples.push({ at: now, tokens: count });
571996
+ return currentTokenRate(samples, now);
571997
+ }
571998
+ function estimateTextTokens(text) {
571999
+ const visible = Array.from(text).length;
572000
+ return visible > 0 ? Math.max(1, Math.ceil(visible / 4)) : 0;
572001
+ }
572002
+ function estimateStreamingOutputTokens(chunkText) {
572003
+ let contentChars = 0;
572004
+ for (const line of chunkText.split("\n")) {
572005
+ const trimmed = line.trim();
572006
+ if (!trimmed.startsWith("data:")) continue;
572007
+ const payload = trimmed.slice(5).trim();
572008
+ if (!payload || payload === "[DONE]") continue;
572009
+ try {
572010
+ const parsed = JSON.parse(payload);
572011
+ const choice = Array.isArray(parsed?.choices) ? parsed.choices[0] : null;
572012
+ const deltaContent = choice?.delta?.content;
572013
+ const messageContent = choice?.message?.content;
572014
+ const responseContent = parsed?.response;
572015
+ const text = typeof deltaContent === "string" ? deltaContent : typeof messageContent === "string" ? messageContent : typeof responseContent === "string" ? responseContent : "";
572016
+ contentChars += Array.from(text).length;
572017
+ } catch {
572018
+ contentChars += Array.from(payload).length;
572019
+ }
572020
+ }
572021
+ if (contentChars > 0) return Math.max(1, Math.ceil(contentChars / 4));
572022
+ return estimateTextTokens(chunkText.trim());
572023
+ }
572024
+ function serializeSponsorModels(stats) {
572025
+ const byModel = /* @__PURE__ */ new Map();
572026
+ for (const [model, requests] of stats.modelUsage.entries()) {
572027
+ if (INTERNAL_CAPABILITIES.has(model)) continue;
572028
+ byModel.set(model, {
572029
+ model,
572030
+ requests,
572031
+ tokensIn: 0,
572032
+ tokensOut: 0,
572033
+ lastUsed: 0
572034
+ });
572035
+ }
572036
+ for (const user of stats.users.values()) {
572037
+ for (const [model, meter] of user.models.entries()) {
572038
+ if (INTERNAL_CAPABILITIES.has(model)) continue;
572039
+ const existing = byModel.get(model) ?? {
572040
+ model,
572041
+ requests: 0,
572042
+ tokensIn: 0,
572043
+ tokensOut: 0,
572044
+ lastUsed: 0
572045
+ };
572046
+ if (!stats.modelUsage.has(model)) existing.requests += meter.requests;
572047
+ existing.tokensIn += meter.tokensIn;
572048
+ existing.tokensOut += meter.tokensOut;
572049
+ existing.lastUsed = Math.max(existing.lastUsed, meter.lastUsed);
572050
+ byModel.set(model, existing);
572051
+ }
572052
+ }
572053
+ return Array.from(byModel.values()).sort(
572054
+ (a2, b) => (b.tokensIn + b.tokensOut || b.requests) - (a2.tokensIn + a2.tokensOut || a2.requests)
572055
+ );
572056
+ }
572057
+ function serializeSponsorPeers(stats) {
572058
+ return Array.from(stats.users.values()).map((user) => ({
572059
+ peer: user.ip,
572060
+ firstSeen: user.firstSeen,
572061
+ lastSeen: user.lastSeen,
572062
+ requests: user.requests,
572063
+ activeRequests: user.activeRequests,
572064
+ tokensIn: user.tokensIn,
572065
+ tokensOut: user.tokensOut,
572066
+ models: Array.from(user.models.entries()).filter(([model]) => !INTERNAL_CAPABILITIES.has(model)).map(([model, meter]) => ({
572067
+ model,
572068
+ requests: meter.requests,
572069
+ tokensIn: meter.tokensIn,
572070
+ tokensOut: meter.tokensOut,
572071
+ lastUsed: meter.lastUsed
572072
+ })).sort((a2, b) => b.tokensIn + b.tokensOut - (a2.tokensIn + a2.tokensOut))
572073
+ })).sort((a2, b) => (b.tokensIn + b.tokensOut || b.requests) - (a2.tokensIn + a2.tokensOut || a2.requests));
572074
+ }
571794
572075
  function nextSponsorDailyReset(now = Date.now()) {
571795
572076
  return now + SPONSOR_DAILY_WINDOW_MS;
571796
572077
  }
@@ -572054,6 +572335,7 @@ var init_expose = __esm({
572054
572335
  /** Sponsor rate limits (set via setSponsorLimits) */
572055
572336
  _sponsorLimits = null;
572056
572337
  _sponsorBlockedRequests = 0;
572338
+ _tokenRateSamples = [];
572057
572339
  _authKey;
572058
572340
  _targetUrl;
572059
572341
  _kind;
@@ -572067,6 +572349,7 @@ var init_expose = __esm({
572067
572349
  errors: 0,
572068
572350
  totalTokensIn: 0,
572069
572351
  totalTokensOut: 0,
572352
+ tokensPerSecond: 0,
572070
572353
  startedAt: Date.now(),
572071
572354
  modelUsage: /* @__PURE__ */ new Map(),
572072
572355
  users: /* @__PURE__ */ new Map(),
@@ -572157,6 +572440,7 @@ var init_expose = __esm({
572157
572440
  };
572158
572441
  }
572159
572442
  refreshSponsorUsageStats(now = Date.now()) {
572443
+ this._stats.tokensPerSecond = currentTokenRate(this._tokenRateSamples, now);
572160
572444
  if (!this._sponsorLimits) {
572161
572445
  this._stats.sponsorUsage = null;
572162
572446
  return;
@@ -572166,6 +572450,10 @@ var init_expose = __esm({
572166
572450
  this._stats.sponsorUsage = {
572167
572451
  enabled: true,
572168
572452
  transport: "tunnel",
572453
+ totalRequests: this._stats.totalRequests,
572454
+ totalTokensIn: this._stats.totalTokensIn,
572455
+ totalTokensOut: this._stats.totalTokensOut,
572456
+ tokensPerSecond: this._stats.tokensPerSecond,
572169
572457
  dailyTokensUsed: this._dailyTokensUsed,
572170
572458
  dailyTokensLimit: this._sponsorLimits.maxTokensPerDay,
572171
572459
  dailyResetAt: this._dailyTokensResetAt,
@@ -572175,9 +572463,15 @@ var init_expose = __esm({
572175
572463
  activeConnections: this._stats.activeConnections,
572176
572464
  maxConcurrent: this._sponsorLimits.maxConcurrent,
572177
572465
  blockedRequests: this._sponsorBlockedRequests,
572178
- allowedModels: this._sponsorLimits.allowedModels === "all" ? "all" : [...this._sponsorLimits.allowedModels]
572466
+ allowedModels: this._sponsorLimits.allowedModels === "all" ? "all" : [...this._sponsorLimits.allowedModels],
572467
+ peers: serializeSponsorPeers(this._stats),
572468
+ models: serializeSponsorModels(this._stats)
572179
572469
  };
572180
572470
  }
572471
+ recordServedTokens(tokens, now = Date.now()) {
572472
+ this._stats.tokensPerSecond = recordTokenRate(this._tokenRateSamples, tokens, now);
572473
+ this.refreshSponsorUsageStats(now);
572474
+ }
572181
572475
  markSponsorBlocked() {
572182
572476
  this._sponsorBlockedRequests++;
572183
572477
  this.refreshSponsorUsageStats();
@@ -572391,8 +572685,11 @@ var init_expose = __esm({
572391
572685
  errors: this._stats.errors,
572392
572686
  totalTokensIn: this._stats.totalTokensIn,
572393
572687
  totalTokensOut: this._stats.totalTokensOut,
572688
+ tokensPerSecond: currentTokenRate(this._tokenRateSamples),
572394
572689
  uptimeSeconds: Math.floor((Date.now() - this._stats.startedAt) / 1e3),
572395
572690
  modelUsage: Object.fromEntries(this._stats.modelUsage),
572691
+ models: serializeSponsorModels(this._stats),
572692
+ peers: serializeSponsorPeers(this._stats),
572396
572693
  users: Array.from(this._stats.users.values()).map((u) => ({
572397
572694
  ip: u.ip,
572398
572695
  requests: u.requests,
@@ -572415,6 +572712,7 @@ var init_expose = __esm({
572415
572712
  return;
572416
572713
  }
572417
572714
  const userIp = req2.headers["cf-connecting-ip"] ?? req2.headers["x-forwarded-for"]?.split(",")[0]?.trim() ?? req2.socket.remoteAddress ?? "unknown";
572715
+ const requestStartedAt = Date.now();
572418
572716
  let user = this._stats.users.get(userIp);
572419
572717
  if (!user) {
572420
572718
  user = {
@@ -572564,6 +572862,9 @@ var init_expose = __esm({
572564
572862
  }
572565
572863
  };
572566
572864
  let responseTail = "";
572865
+ let requestTokensIn = 0;
572866
+ let requestTokensOut = 0;
572867
+ let sawStreamTokenEstimate = false;
572567
572868
  const finalizeRequest = () => {
572568
572869
  user.activeRequests = Math.max(0, user.activeRequests - 1);
572569
572870
  this._stats.activeConnections = Math.max(0, this._stats.activeConnections - 1);
@@ -572573,9 +572874,12 @@ var init_expose = __esm({
572573
572874
  if (promptEval || evalCount) {
572574
572875
  const tIn2 = parseInt(promptEval?.[1] ?? "0", 10);
572575
572876
  const tOut2 = parseInt(evalCount?.[1] ?? "0", 10);
572877
+ requestTokensIn = tIn2;
572878
+ requestTokensOut = tOut2;
572576
572879
  this._stats.totalTokensIn += tIn2;
572577
572880
  this._stats.totalTokensOut += tOut2;
572578
572881
  this.trackTokenUsage(tIn2, tOut2);
572882
+ if (!isStreaming || !sawStreamTokenEstimate) this.recordServedTokens(tOut2);
572579
572883
  user.tokensIn += tIn2;
572580
572884
  user.tokensOut += tOut2;
572581
572885
  if (requestModel) {
@@ -572591,9 +572895,12 @@ var init_expose = __esm({
572591
572895
  if (promptTokens || completionTokens) {
572592
572896
  const tIn2 = parseInt(promptTokens?.[1] ?? "0", 10);
572593
572897
  const tOut2 = parseInt(completionTokens?.[1] ?? "0", 10);
572898
+ requestTokensIn = tIn2;
572899
+ requestTokensOut = tOut2;
572594
572900
  this._stats.totalTokensIn += tIn2;
572595
572901
  this._stats.totalTokensOut += tOut2;
572596
572902
  this.trackTokenUsage(tIn2, tOut2);
572903
+ if (!isStreaming || !sawStreamTokenEstimate) this.recordServedTokens(tOut2);
572597
572904
  user.tokensIn += tIn2;
572598
572905
  user.tokensOut += tOut2;
572599
572906
  if (requestModel) {
@@ -572607,8 +572914,8 @@ var init_expose = __esm({
572607
572914
  }
572608
572915
  } catch {
572609
572916
  }
572610
- const tIn = user.tokensIn;
572611
- const tOut = user.tokensOut;
572917
+ const tIn = requestTokensIn;
572918
+ const tOut = requestTokensOut;
572612
572919
  if (tIn > 0 || tOut > 0) {
572613
572920
  const receipt = {
572614
572921
  job_id: `job-${Date.now().toString(36)}`,
@@ -572616,7 +572923,7 @@ var init_expose = __esm({
572616
572923
  consumer_ip: userIp,
572617
572924
  model: requestModel,
572618
572925
  usage_final: { input_tokens: tIn, output_tokens: tOut },
572619
- latency_ms: Date.now() - (user.lastSeen || Date.now()),
572926
+ latency_ms: Date.now() - requestStartedAt,
572620
572927
  quality_flags: [],
572621
572928
  // COHERE revenue split: 70% provider, 10% commons, 8% memory, 7% relay, 5% reserve
572622
572929
  provider_reward: (tIn + tOut) * 1e-7 * 0.7,
@@ -572656,6 +572963,11 @@ var init_expose = __esm({
572656
572963
  }
572657
572964
  if (isStreaming) {
572658
572965
  this.emit("token_flash");
572966
+ const estimatedTokens = estimateStreamingOutputTokens(text);
572967
+ if (estimatedTokens > 0) {
572968
+ sawStreamTokenEstimate = true;
572969
+ this.recordServedTokens(estimatedTokens);
572970
+ }
572659
572971
  this.emit("stream_data", { content: text, model: requestModel, peer: userIp });
572660
572972
  }
572661
572973
  });
@@ -572953,6 +573265,7 @@ ${this.formatConnectionInfo()}`);
572953
573265
  lines.push(` ${c3.cyan("Errors".padEnd(18))} ${s2.errors}`);
572954
573266
  lines.push(` ${c3.cyan("Tokens in".padEnd(18))} ${fmtTokens(s2.totalTokensIn)}`);
572955
573267
  lines.push(` ${c3.cyan("Tokens out".padEnd(18))} ${fmtTokens(s2.totalTokensOut)}`);
573268
+ lines.push(` ${c3.cyan("Tokens/sec".padEnd(18))} ${s2.tokensPerSecond.toFixed(s2.tokensPerSecond >= 10 ? 0 : 1)} t/s`);
572956
573269
  if (s2.budgetTokensTotal > 0) {
572957
573270
  const pct = Math.round(s2.budgetTokensRemaining / s2.budgetTokensTotal * 100);
572958
573271
  const budgetColor = pct > 50 ? c3.green : pct > 20 ? c3.yellow : c3.red;
@@ -573042,8 +573355,10 @@ ${this.formatConnectionInfo()}`);
573042
573355
  _loadbalance = false;
573043
573356
  _endpointAuth;
573044
573357
  _sponsorLimits = null;
573358
+ _lastPushedSponsorLimitsKey = "";
573045
573359
  _sponsorBlockedRequests = 0;
573046
573360
  _sponsorRequestWindow = [];
573361
+ _tokenRateSamples = [];
573047
573362
  _dailyTokensUsed = 0;
573048
573363
  _dailyTokensResetAt = 0;
573049
573364
  _pollTimer = null;
@@ -573059,6 +573374,7 @@ ${this.formatConnectionInfo()}`);
573059
573374
  errors: 0,
573060
573375
  totalTokensIn: 0,
573061
573376
  totalTokensOut: 0,
573377
+ tokensPerSecond: 0,
573062
573378
  startedAt: Date.now(),
573063
573379
  modelUsage: /* @__PURE__ */ new Map(),
573064
573380
  users: /* @__PURE__ */ new Map(),
@@ -573115,6 +573431,7 @@ ${this.formatConnectionInfo()}`);
573115
573431
  this.ensureSponsorDailyWindow();
573116
573432
  this.refreshSponsorUsageStats();
573117
573433
  this.emitStats();
573434
+ if (this._stats.status === "active") this.pushSponsorLimitsToDaemon();
573118
573435
  }
573119
573436
  getSponsorUsageSnapshot() {
573120
573437
  this.refreshSponsorUsageStats();
@@ -573174,6 +573491,7 @@ ${this.formatConnectionInfo()}`);
573174
573491
  this.refreshSponsorUsageStats();
573175
573492
  }
573176
573493
  refreshSponsorUsageStats(now = Date.now()) {
573494
+ this._stats.tokensPerSecond = currentTokenRate(this._tokenRateSamples, now);
573177
573495
  if (!this._sponsorLimits) {
573178
573496
  this._stats.sponsorUsage = null;
573179
573497
  return;
@@ -573183,6 +573501,10 @@ ${this.formatConnectionInfo()}`);
573183
573501
  this._stats.sponsorUsage = {
573184
573502
  enabled: true,
573185
573503
  transport: "libp2p",
573504
+ totalRequests: this._stats.totalRequests,
573505
+ totalTokensIn: this._stats.totalTokensIn,
573506
+ totalTokensOut: this._stats.totalTokensOut,
573507
+ tokensPerSecond: this._stats.tokensPerSecond,
573186
573508
  dailyTokensUsed: this._dailyTokensUsed,
573187
573509
  dailyTokensLimit: this._sponsorLimits.maxTokensPerDay,
573188
573510
  dailyResetAt: this._dailyTokensResetAt,
@@ -573192,9 +573514,47 @@ ${this.formatConnectionInfo()}`);
573192
573514
  activeConnections: this._stats.activeConnections,
573193
573515
  maxConcurrent: this._sponsorLimits.maxConcurrent,
573194
573516
  blockedRequests: this._sponsorBlockedRequests,
573195
- allowedModels: this._sponsorLimits.allowedModels === "all" ? "all" : [...this._sponsorLimits.allowedModels]
573517
+ allowedModels: this._sponsorLimits.allowedModels === "all" ? "all" : [...this._sponsorLimits.allowedModels],
573518
+ peers: serializeSponsorPeers(this._stats),
573519
+ models: serializeSponsorModels(this._stats)
573196
573520
  };
573197
573521
  }
573522
+ recordServedTokens(tokens, now = Date.now()) {
573523
+ this._stats.tokensPerSecond = recordTokenRate(this._tokenRateSamples, tokens, now);
573524
+ this.refreshSponsorUsageStats(now);
573525
+ }
573526
+ buildExposeArgs() {
573527
+ const exposeArgs = {
573528
+ action: "expose",
573529
+ ollama_url: this._targetUrl,
573530
+ margin: String(this._margin),
573531
+ auth_key: this._authKey
573532
+ };
573533
+ if (this._passthrough) {
573534
+ exposeArgs.passthrough = "true";
573535
+ if (this._endpointAuth) exposeArgs.endpoint_auth = this._endpointAuth;
573536
+ }
573537
+ if (this._sponsorLimits) {
573538
+ exposeArgs.max_concurrent = String(this._sponsorLimits.maxConcurrent);
573539
+ exposeArgs.max_requests_per_minute = String(this._sponsorLimits.maxRequestsPerMinute);
573540
+ exposeArgs.max_tokens_per_day = String(this._sponsorLimits.maxTokensPerDay);
573541
+ exposeArgs.daily_tokens_used = String(this._dailyTokensUsed);
573542
+ exposeArgs.daily_tokens_reset_at = String(this._dailyTokensResetAt);
573543
+ exposeArgs.allowed_models = this._sponsorLimits.allowedModels === "all" ? "all" : this._sponsorLimits.allowedModels.join(",");
573544
+ }
573545
+ return exposeArgs;
573546
+ }
573547
+ pushSponsorLimitsToDaemon() {
573548
+ if (!this._nexusTool || this._stats.status !== "active") return;
573549
+ const exposeArgs = this.buildExposeArgs();
573550
+ const key = JSON.stringify(exposeArgs);
573551
+ if (key === this._lastPushedSponsorLimitsKey) return;
573552
+ this._lastPushedSponsorLimitsKey = key;
573553
+ void this._nexusTool.execute(exposeArgs).catch((err) => {
573554
+ this._lastPushedSponsorLimitsKey = "";
573555
+ this._onError?.(`P2P sponsor limit update failed: ${err instanceof Error ? err.message : String(err)}`);
573556
+ });
573557
+ }
573198
573558
  async start() {
573199
573559
  this._onInfo?.("Connecting to nexus P2P network...");
573200
573560
  const connectResult = await this._nexusTool.execute({
@@ -573207,18 +573567,7 @@ ${this.formatConnectionInfo()}`);
573207
573567
  }
573208
573568
  await new Promise((r2) => setTimeout(r2, 500));
573209
573569
  this._onInfo?.(this._passthrough ? `Registering passthrough capabilities (→ ${this._targetUrl})...` : "Registering inference capabilities...");
573210
- const exposeArgs = {
573211
- action: "expose",
573212
- ollama_url: this._targetUrl,
573213
- margin: String(this._margin),
573214
- auth_key: this._authKey
573215
- };
573216
- if (this._passthrough) {
573217
- exposeArgs.passthrough = "true";
573218
- if (this._endpointAuth) {
573219
- exposeArgs.endpoint_auth = this._endpointAuth;
573220
- }
573221
- }
573570
+ const exposeArgs = this.buildExposeArgs();
573222
573571
  let exposeResult = await this._nexusTool.execute(exposeArgs);
573223
573572
  if (!exposeResult.success && exposeResult.error?.includes("not running")) {
573224
573573
  await new Promise((r2) => setTimeout(r2, 1500));
@@ -573355,7 +573704,8 @@ ${this.formatConnectionInfo()}`);
573355
573704
  const invocCount = files.length;
573356
573705
  const newRequests = invocCount - this._prevInvocCount;
573357
573706
  if (newRequests > 0) {
573358
- this._stats.activeConnections = Math.max(1, newRequests);
573707
+ const activeLimit2 = this._sponsorLimits?.maxConcurrent ?? 10;
573708
+ this._stats.activeConnections = Math.min(Math.max(1, newRequests), activeLimit2);
573359
573709
  this._stats.totalRequests = invocCount;
573360
573710
  this._prevInvocCount = invocCount;
573361
573711
  this.emitStats();
@@ -573380,7 +573730,9 @@ ${this.formatConnectionInfo()}`);
573380
573730
  }
573381
573731
  const inFlightEstimate = Math.max(0, invocCount - meteringLines);
573382
573732
  const prevActive = this._stats.activeConnections;
573383
- this._stats.activeConnections = Math.max(recentActive, Math.min(inFlightEstimate, 10));
573733
+ const activeEstimate = Math.max(recentActive, Math.min(inFlightEstimate, 10));
573734
+ const activeLimit = this._sponsorLimits?.maxConcurrent ?? 10;
573735
+ this._stats.activeConnections = Math.min(activeEstimate, activeLimit);
573384
573736
  if (this._stats.activeConnections !== prevActive) this.emitStats();
573385
573737
  if (this._stats.activeConnections > 0 && !this._tokenFlashTimer) {
573386
573738
  this.emit("token_flash");
@@ -573432,6 +573784,13 @@ ${this.formatConnectionInfo()}`);
573432
573784
  if (!line.trim()) continue;
573433
573785
  try {
573434
573786
  const record = JSON.parse(line);
573787
+ if (record.blocked) {
573788
+ this._sponsorBlockedRequests++;
573789
+ this._stats.errors++;
573790
+ this.recordSponsorRequest();
573791
+ this.refreshSponsorUsageStats();
573792
+ continue;
573793
+ }
573435
573794
  let tokIn = 0;
573436
573795
  let tokOut = 0;
573437
573796
  if (typeof record.inputTokens === "number" && typeof record.outputTokens === "number") {
@@ -573452,6 +573811,7 @@ ${this.formatConnectionInfo()}`);
573452
573811
  }
573453
573812
  this._stats.totalTokensIn += tokIn;
573454
573813
  this._stats.totalTokensOut += tokOut;
573814
+ this.recordServedTokens(tokOut);
573455
573815
  this.recordSponsorRequest();
573456
573816
  this.trackTokenUsage(tokIn, tokOut);
573457
573817
  const peerId = record.from || record.peerId || "unknown";
@@ -573565,6 +573925,7 @@ ${this.formatConnectionInfo()}`);
573565
573925
  lines.push(` ${c3.cyan("Errors".padEnd(18))} ${s2.errors}`);
573566
573926
  lines.push(` ${c3.cyan("Tokens in".padEnd(18))} ${fmtTokens(s2.totalTokensIn)}`);
573567
573927
  lines.push(` ${c3.cyan("Tokens out".padEnd(18))} ${fmtTokens(s2.totalTokensOut)}`);
573928
+ lines.push(` ${c3.cyan("Tokens/sec".padEnd(18))} ${s2.tokensPerSecond.toFixed(s2.tokensPerSecond >= 10 ? 0 : 1)} t/s`);
573568
573929
  if (s2.budgetTokensTotal > 0) {
573569
573930
  const pct = Math.round(s2.budgetTokensRemaining / s2.budgetTokensTotal * 100);
573570
573931
  const budgetColor = pct > 50 ? c3.green : pct > 20 ? c3.yellow : c3.red;
@@ -578973,6 +579334,7 @@ var init_status_bar = __esm({
578973
579334
  setExposeStatus(status) {
578974
579335
  this._expose = status;
578975
579336
  this._exposePeerCount = status.activeConnections;
579337
+ this.setRemoteTokensPerSecond(status.tokensPerSecond);
578976
579338
  if (this.active) this.renderFooterPreserveCursor();
578977
579339
  }
578978
579340
  /** Clear expose gateway status */
@@ -579008,27 +579370,41 @@ var init_status_bar = __esm({
579008
579370
  }
579009
579371
  /** Unified system metrics collector (local or remote) */
579010
579372
  _metricsCollector = new SystemMetricsCollector();
579011
- /** Cached unified metrics snapshot — updated by collector callback */
579373
+ /** Cached local metrics snapshot — updated by collector callback */
579012
579374
  _unifiedMetrics = null;
579375
+ _localUnifiedMetrics = null;
579376
+ _remoteUnifiedMetrics = null;
579377
+ _remoteMetricsUpdatedAt = 0;
579013
579378
  /** Legacy remote metrics polling timer (for peer/HTTP polling) */
579014
579379
  _remoteMetricsTimer = null;
579380
+ setRemoteTokensPerSecond(rate) {
579381
+ const n2 = typeof rate === "number" ? rate : Number(rate);
579382
+ if (!Number.isFinite(n2) || n2 < 0) return;
579383
+ this._tokensPerSecond = n2;
579384
+ if (n2 > this._peakTokensPerSecond) this._peakTokensPerSecond = n2;
579385
+ }
579386
+ getDisplayMetrics() {
579387
+ const local = this._localUnifiedMetrics ?? (this._unifiedMetrics?.source === "local" ? this._unifiedMetrics : null) ?? getInstantSnapshot();
579388
+ const remote = this._remoteUnifiedMetrics;
579389
+ const remoteFresh = remote && Date.now() - this._remoteMetricsUpdatedAt < 6e4;
579390
+ if (!remoteFresh) return local;
579391
+ const showRemote = Math.floor(Date.now() / 5e3) % 2 === 1;
579392
+ if (!showRemote) return local;
579393
+ return {
579394
+ ...remote,
579395
+ network: local.network
579396
+ };
579397
+ }
579015
579398
  /** Update remote host system metrics (from polling /v1/system/metrics) */
579016
579399
  setRemoteMetrics(metrics2) {
579017
- if (!this._metricsCollector.isActive || this._metricsCollector.source !== "remote") {
579018
- this._metricsCollector.startRemote((m2) => {
579019
- this._unifiedMetrics = m2;
579020
- this._gpuName = m2.gpuName || "";
579021
- this._vramTotal = m2.vramTotalMB || 0;
579022
- this._vramUsed = m2.vramUsedMB || 0;
579023
- if (this.active) this.renderFooterPreserveCursor();
579024
- });
579025
- }
579026
- this._metricsCollector.pushRemoteMetrics({
579400
+ const hardware = {
579027
579401
  cpuUtil: metrics2.cpuUtil,
579028
579402
  cpuCores: metrics2.cpuCores ?? 0,
579029
579403
  cpuModel: metrics2.cpuModel ?? "",
579030
579404
  gpuUtil: metrics2.gpuUtil,
579405
+ gpuCount: metrics2.gpuUtil >= 0 || metrics2.gpuName ? 1 : 0,
579031
579406
  gpuName: metrics2.gpuName,
579407
+ gpuDevices: [],
579032
579408
  vramUtil: metrics2.vramUtil,
579033
579409
  vramUsedMB: metrics2.vramUsedMB ?? 0,
579034
579410
  vramTotalMB: metrics2.vramTotalMB ?? 0,
@@ -579039,17 +579415,30 @@ var init_status_bar = __esm({
579039
579415
  diskUsedGB: metrics2.diskUsedGB ?? 0,
579040
579416
  diskTotalGB: metrics2.diskTotalGB ?? 0,
579041
579417
  diskFreeGB: metrics2.diskFreeGB ?? 0,
579042
- diskPath: metrics2.diskPath ?? ""
579043
- });
579418
+ diskPath: metrics2.diskPath ?? "",
579419
+ ollamaPool: null
579420
+ };
579421
+ const local = this._localUnifiedMetrics ?? this._unifiedMetrics ?? getInstantSnapshot();
579422
+ this._remoteUnifiedMetrics = {
579423
+ source: "remote",
579424
+ hardware,
579425
+ network: local.network
579426
+ };
579427
+ this._remoteMetricsUpdatedAt = Date.now();
579428
+ this.setRemoteTokensPerSecond(metrics2.tokensPerSecond);
579429
+ if (this.active) this.renderFooterPreserveCursor();
579044
579430
  }
579045
579431
  /** Clear remote metrics and switch back to local collection */
579046
579432
  clearRemoteMetrics() {
579047
- this._unifiedMetrics = null;
579433
+ this._remoteUnifiedMetrics = null;
579434
+ this._remoteMetricsUpdatedAt = 0;
579048
579435
  if (this._remoteMetricsTimer) {
579049
579436
  clearInterval(this._remoteMetricsTimer);
579050
579437
  this._remoteMetricsTimer = null;
579051
579438
  }
579052
- this.startLocalMetrics();
579439
+ if (!this._metricsCollector.isActive || this._metricsCollector.source !== "local") {
579440
+ this.startLocalMetrics();
579441
+ }
579053
579442
  if (this.active) this.renderFooterPreserveCursor();
579054
579443
  }
579055
579444
  /**
@@ -579058,7 +579447,14 @@ var init_status_bar = __esm({
579058
579447
  */
579059
579448
  startLocalMetrics(intervalMs = 2e3) {
579060
579449
  this._metricsCollector.startLocal((m2) => {
579450
+ this._localUnifiedMetrics = m2;
579061
579451
  this._unifiedMetrics = m2;
579452
+ if (this._remoteUnifiedMetrics) {
579453
+ this._remoteUnifiedMetrics = {
579454
+ ...this._remoteUnifiedMetrics,
579455
+ network: m2.network
579456
+ };
579457
+ }
579062
579458
  if (this.active) this.renderFooterPreserveCursor();
579063
579459
  }, intervalMs);
579064
579460
  try {
@@ -579095,6 +579491,9 @@ var init_status_bar = __esm({
579095
579491
  stopAllMetrics() {
579096
579492
  this._metricsCollector.stop();
579097
579493
  this._unifiedMetrics = null;
579494
+ this._localUnifiedMetrics = null;
579495
+ this._remoteUnifiedMetrics = null;
579496
+ this._remoteMetricsUpdatedAt = 0;
579098
579497
  if (this._remoteMetricsTimer) {
579099
579498
  clearInterval(this._remoteMetricsTimer);
579100
579499
  this._remoteMetricsTimer = null;
@@ -579106,10 +579505,6 @@ var init_status_bar = __esm({
579106
579505
  */
579107
579506
  startRemoteMetricsPolling(endpointUrl, authKey) {
579108
579507
  this.stopRemoteMetricsPolling();
579109
- this._metricsCollector.startRemote((m2) => {
579110
- this._unifiedMetrics = m2;
579111
- if (this.active) this.renderFooterPreserveCursor();
579112
- });
579113
579508
  const poll = async () => {
579114
579509
  try {
579115
579510
  const url = new URL("/v1/system/metrics", endpointUrl);
@@ -579131,7 +579526,8 @@ var init_status_bar = __esm({
579131
579526
  diskUsedGB: data.disk?.usedGB ?? 0,
579132
579527
  diskTotalGB: data.disk?.totalGB ?? 0,
579133
579528
  diskFreeGB: data.disk?.freeGB ?? 0,
579134
- diskPath: data.disk?.path ?? ""
579529
+ diskPath: data.disk?.path ?? "",
579530
+ tokensPerSecond: data.gateway?.tokensPerSecond
579135
579531
  });
579136
579532
  }
579137
579533
  } catch {
@@ -579147,10 +579543,6 @@ var init_status_bar = __esm({
579147
579543
  */
579148
579544
  startPeerMetricsPolling(sendCommand, peerId, authKey, nexusDir) {
579149
579545
  this.stopRemoteMetricsPolling();
579150
- this._metricsCollector.startRemote((m2) => {
579151
- this._unifiedMetrics = m2;
579152
- if (this.active) this.renderFooterPreserveCursor();
579153
- });
579154
579546
  let pollAttempt = 0;
579155
579547
  const extractMetrics = (raw) => {
579156
579548
  let obj = raw;
@@ -579217,6 +579609,7 @@ var init_status_bar = __esm({
579217
579609
  const cached = JSON.parse(raw);
579218
579610
  if (cached && cached.ts && Date.now() - cached.ts < 6e4) {
579219
579611
  const m2 = cached.data;
579612
+ this.setRemoteTokensPerSecond(m2?.gateway?.tokensPerSecond);
579220
579613
  if (m2?.cpu) {
579221
579614
  lastPeerMetricsDebug = `ok: cpu=${m2.cpu?.utilization}%`;
579222
579615
  this.setRemoteMetrics({
@@ -579235,7 +579628,8 @@ var init_status_bar = __esm({
579235
579628
  diskTotalGB: m2.disk?.totalGB ?? 0,
579236
579629
  diskUsedGB: m2.disk?.usedGB ?? 0,
579237
579630
  diskFreeGB: m2.disk?.freeGB ?? 0,
579238
- diskPath: m2.disk?.path ?? ""
579631
+ diskPath: m2.disk?.path ?? "",
579632
+ tokensPerSecond: m2.gateway?.tokensPerSecond
579239
579633
  });
579240
579634
  return;
579241
579635
  }
@@ -579263,7 +579657,11 @@ var init_status_bar = __esm({
579263
579657
  clearInterval(this._remoteMetricsTimer);
579264
579658
  this._remoteMetricsTimer = null;
579265
579659
  }
579266
- this.startLocalMetrics();
579660
+ this._remoteUnifiedMetrics = null;
579661
+ this._remoteMetricsUpdatedAt = 0;
579662
+ if (!this._metricsCollector.isActive || this._metricsCollector.source !== "local") {
579663
+ this.startLocalMetrics();
579664
+ }
579267
579665
  }
579268
579666
  /** Update token metrics from a token_usage event */
579269
579667
  updateMetrics(update2) {
@@ -579432,7 +579830,7 @@ var init_status_bar = __esm({
579432
579830
  // 10: █ full block
579433
579831
  ];
579434
579832
  if (this._focusFrame < 4) return DENSITY2[10];
579435
- const m2 = this._unifiedMetrics ?? getInstantSnapshot();
579833
+ const m2 = this.getDisplayMetrics();
579436
579834
  const cpu = m2.hardware.cpuUtil;
579437
579835
  const gpu = m2.hardware.gpuUtil;
579438
579836
  const mem = m2.hardware.memUtil;
@@ -580898,7 +581296,7 @@ ${CONTENT_BG_SEQ}`);
580898
581296
  });
580899
581297
  }
580900
581298
  {
580901
- const um = this._unifiedMetrics ?? getInstantSnapshot();
581299
+ const um = this.getDisplayMetrics();
580902
581300
  const rm4 = um.hardware;
580903
581301
  const isLocal = um.source === "local";
580904
581302
  const srcTag = isLocal ? pastel2(120, "L") : pastel2(117, "R");
@@ -590531,6 +590929,15 @@ __export(sponsor_wizard_exports, {
590531
590929
  });
590532
590930
  import { existsSync as existsSync104, readFileSync as readFileSync83, writeFileSync as writeFileSync52, mkdirSync as mkdirSync57 } from "node:fs";
590533
590931
  import { join as join118 } from "node:path";
590932
+ function fmtTokens2(n2) {
590933
+ if (n2 < 1e3) return String(Math.max(0, Math.floor(n2)));
590934
+ if (n2 < 1e6) return `${(n2 / 1e3).toFixed(1)}K`;
590935
+ return `${(n2 / 1e6).toFixed(1)}M`;
590936
+ }
590937
+ function fmtTps(n2) {
590938
+ if (!Number.isFinite(n2) || n2 <= 0) return "0";
590939
+ return n2 >= 10 ? n2.toFixed(0) : n2.toFixed(1);
590940
+ }
590534
590941
  function sponsorDir(projectDir2) {
590535
590942
  return join118(projectDir2, ".omnius", "sponsor");
590536
590943
  }
@@ -591312,7 +591719,13 @@ async function showSponsorDashboard(config, projectDir2, rl, availableRows, spon
591312
591719
  const dailyTokensLimit = sponsorUsage?.dailyTokensLimit || config.rateLimits.maxTokensPerDay;
591313
591720
  const requestsPerMinuteLimit = sponsorUsage?.requestsPerMinuteLimit || config.rateLimits.maxRequestsPerMinute;
591314
591721
  const maxConcurrent = sponsorUsage?.maxConcurrent || config.rateLimits.maxConcurrent;
591722
+ const topModels = (sponsorUsage?.models ?? []).slice(0, 5);
591723
+ const topPeers = (sponsorUsage?.peers ?? []).slice(0, 5);
591315
591724
  const usageItems = [
591725
+ {
591726
+ key: "info_usage_totals",
591727
+ label: ` Totals: ${sponsorUsage?.totalRequests ?? 0} req · in ${fmtTokens2(sponsorUsage?.totalTokensIn ?? 0)} · out ${fmtTokens2(sponsorUsage?.totalTokensOut ?? 0)} · ${fmtTps(sponsorUsage?.tokensPerSecond ?? 0)} t/s`
591728
+ },
591316
591729
  {
591317
591730
  key: "info_usage_daily",
591318
591731
  label: ` ${formatUsageBar({
@@ -591344,12 +591757,31 @@ async function showSponsorDashboard(config, projectDir2, rl, availableRows, spon
591344
591757
  label: ` Blocked: ${sponsorUsage?.blockedRequests ?? 0}`
591345
591758
  }
591346
591759
  ];
591760
+ if (topModels.length > 0) {
591761
+ usageItems.push({ key: "info_usage_models_hdr", label: " Models" });
591762
+ for (const [idx, model] of topModels.entries()) {
591763
+ usageItems.push({
591764
+ key: `info_usage_model_${idx}`,
591765
+ label: ` ${model.model}: ${model.requests} req · ${fmtTokens2(model.tokensIn + model.tokensOut)} tok`
591766
+ });
591767
+ }
591768
+ }
591769
+ if (topPeers.length > 0) {
591770
+ usageItems.push({ key: "info_usage_peers_hdr", label: " Peers" });
591771
+ for (const [idx, peer] of topPeers.entries()) {
591772
+ const active = peer.activeRequests > 0 ? ` · ${peer.activeRequests} active` : "";
591773
+ usageItems.push({
591774
+ key: `info_usage_peer_${idx}`,
591775
+ label: ` ${peer.peer}: ${peer.requests} req · ${fmtTokens2(peer.tokensIn + peer.tokensOut)} tok${active}`
591776
+ });
591777
+ }
591778
+ }
591347
591779
  const items = [
591348
591780
  { key: "hdr", label: "Sponsor Dashboard" },
591349
591781
  { key: "info_status", label: ` Status: ${isPaused ? "● PAUSED" : "● ACTIVE"}` },
591350
591782
  { key: "info_ep", label: ` Endpoints: ${enabledEps.map((e2) => e2.label).join(", ")}` },
591351
591783
  { key: "info_transport", label: ` Transport: ${[config.transport.cloudflared ? "Cloudflared" : "", config.transport.libp2p ? "libp2p" : ""].filter(Boolean).join(" + ")}` },
591352
- { key: "info_limits", label: ` Limits: ${config.rateLimits.maxRequestsPerMinute} req/min, ${config.rateLimits.maxTokensPerDay.toLocaleString()} tokens/day` },
591784
+ { key: "info_limits", label: ` Limits: ${config.rateLimits.maxRequestsPerMinute} req/min, ${config.rateLimits.maxTokensPerDay.toLocaleString()} tokens/day, ${config.rateLimits.maxConcurrent} concurrent` },
591353
591785
  { key: "info_usage_hdr", label: " Usage" },
591354
591786
  ...usageItems,
591355
591787
  { key: "sep", label: "" },
@@ -591361,7 +591793,7 @@ async function showSponsorDashboard(config, projectDir2, rl, availableRows, spon
591361
591793
  items,
591362
591794
  title: "Sponsor Dashboard",
591363
591795
  rl,
591364
- skipKeys: ["hdr", "sep", "info_status", "info_ep", "info_transport", "info_limits", "info_usage_hdr", "info_usage_daily", "info_usage_rpm", "info_usage_concurrent", "info_usage_blocked"],
591796
+ skipKeys: items.map((item) => item.key).filter((key) => !["modify", "pause", "resume", "remove"].includes(key)),
591365
591797
  availableRows
591366
591798
  });
591367
591799
  if (!result.confirmed) return "close";
@@ -595626,6 +596058,18 @@ import {
595626
596058
  writeSync as writeSync2
595627
596059
  } from "node:fs";
595628
596060
  import { relative as relative11, join as join120 } from "node:path";
596061
+ async function parseJsonResponse(resp, source) {
596062
+ const body = await resp.text();
596063
+ const trimmed = body.trim();
596064
+ if (!trimmed) {
596065
+ throw new Error(`${source} returned an empty response${resp.status ? ` (HTTP ${resp.status})` : ""}`);
596066
+ }
596067
+ try {
596068
+ return JSON.parse(trimmed);
596069
+ } catch {
596070
+ throw new Error(`${source} returned malformed JSON${resp.status ? ` (HTTP ${resp.status})` : ""}`);
596071
+ }
596072
+ }
595629
596073
  async function _immediateReregister(newUrl) {
595630
596074
  if (!_lastRegisteredSponsorPayload) return;
595631
596075
  _lastRegisteredSponsorPayload.tunnelUrl = newUrl;
@@ -600471,7 +600915,8 @@ sleep 1
600471
600915
  authKey: tunnelGw?.authKey || "",
600472
600916
  limits: {
600473
600917
  maxRequestsPerMinute: config.rateLimits.maxRequestsPerMinute,
600474
- maxTokensPerDay: config.rateLimits.maxTokensPerDay
600918
+ maxTokensPerDay: config.rateLimits.maxTokensPerDay,
600919
+ maxConcurrent: config.rateLimits.maxConcurrent
600475
600920
  },
600476
600921
  banner: "none",
600477
600922
  message: config.header.message || sponsorName,
@@ -600495,7 +600940,10 @@ sleep 1
600495
600940
  signal: AbortSignal.timeout(1e4)
600496
600941
  }
600497
600942
  );
600498
- const kvResult = await kvResp.json();
600943
+ const kvResult = await parseJsonResponse(
600944
+ kvResp,
600945
+ "Sponsor directory"
600946
+ );
600499
600947
  if (kvResult.persisted) {
600500
600948
  _spLog("KV registration: persisted");
600501
600949
  renderInfo(
@@ -605784,7 +606232,7 @@ async function handleSponsoredEndpoint(ctx3, local) {
605784
606232
  signal: AbortSignal.timeout(5e3)
605785
606233
  });
605786
606234
  if (kvResp.ok) {
605787
- const kvData = await kvResp.json();
606235
+ const kvData = await parseJsonResponse(kvResp, "Sponsor directory");
605788
606236
  const kvSponsors = (kvData.sponsors || []).filter(
605789
606237
  (s2) => s2.status === "active"
605790
606238
  );
@@ -616317,7 +616765,7 @@ function fmtDuration(ms) {
616317
616765
  const rm4 = m2 % 60;
616318
616766
  return `${h}h ${rm4}m`;
616319
616767
  }
616320
- function fmtTokens2(n2) {
616768
+ function fmtTokens3(n2) {
616321
616769
  if (n2 < 1e3) return String(n2);
616322
616770
  if (n2 < 1e6) return `${(n2 / 1e3).toFixed(1)}K`;
616323
616771
  return `${(n2 / 1e6).toFixed(2)}M`;
@@ -616346,8 +616794,8 @@ function buildMetricEntries(snap, scope) {
616346
616794
  entries.push({
616347
616795
  icon: "",
616348
616796
  label: "Tokens",
616349
- value: fmtTokens2(snap.totalTokens),
616350
- detail: `Prompt: ${fmtTokens2(snap.totalPromptTokens)} · Completion: ${fmtTokens2(snap.totalCompletionTokens)}`,
616797
+ value: fmtTokens3(snap.totalTokens),
616798
+ detail: `Prompt: ${fmtTokens3(snap.totalPromptTokens)} · Completion: ${fmtTokens3(snap.totalCompletionTokens)}`,
616351
616799
  category: "inference"
616352
616800
  });
616353
616801
  entries.push({
@@ -616383,14 +616831,14 @@ function buildMetricEntries(snap, scope) {
616383
616831
  entries.push({
616384
616832
  icon: "",
616385
616833
  label: "Context Window",
616386
- value: fmtTokens2(snap.contextWindowSize),
616834
+ value: fmtTokens3(snap.contextWindowSize),
616387
616835
  category: "context"
616388
616836
  });
616389
616837
  entries.push({
616390
616838
  icon: "",
616391
616839
  label: "Context Used",
616392
- value: fmtTokens2(snap.estimatedContextTokens),
616393
- detail: `Utilization: ${fmtPct(snap.contextUtilizationPct)} · Peak: ${fmtTokens2(snap.peakContextTokens)}`,
616840
+ value: fmtTokens3(snap.estimatedContextTokens),
616841
+ detail: `Utilization: ${fmtPct(snap.contextUtilizationPct)} · Peak: ${fmtTokens3(snap.peakContextTokens)}`,
616394
616842
  category: "context"
616395
616843
  });
616396
616844
  entries.push({
@@ -661913,7 +662361,8 @@ Log: ${nexusLogPath}`)
661913
662361
  status: stats.status,
661914
662362
  totalRequests: stats.totalRequests,
661915
662363
  activeConnections: stats.activeConnections,
661916
- modelUsage: stats.modelUsage
662364
+ modelUsage: stats.modelUsage,
662365
+ tokensPerSecond: stats.tokensPerSecond
661917
662366
  });
661918
662367
  });
661919
662368
  reconnected.on("token_flash", () => statusBar.flashExposeToken());
@@ -661956,7 +662405,8 @@ Log: ${nexusLogPath}`)
661956
662405
  status: stats.status,
661957
662406
  totalRequests: stats.totalRequests,
661958
662407
  activeConnections: stats.activeConnections,
661959
- modelUsage: stats.modelUsage
662408
+ modelUsage: stats.modelUsage,
662409
+ tokensPerSecond: stats.tokensPerSecond
661960
662410
  });
661961
662411
  });
661962
662412
  reconnectedP2P.on("token_flash", () => statusBar.flashExposeToken());
@@ -662062,7 +662512,8 @@ Log: ${nexusLogPath}`)
662062
662512
  { signal: AbortSignal.timeout(8e3) }
662063
662513
  );
662064
662514
  if (spResp.ok) {
662065
- const spData = await spResp.json();
662515
+ const spText = await spResp.text();
662516
+ const spData = spText.trim() ? JSON.parse(spText) : { sponsors: [] };
662066
662517
  let active = (spData.sponsors || []).filter(
662067
662518
  (s2) => s2.status === "active" && s2.tunnelUrl
662068
662519
  );
@@ -663848,7 +664299,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
663848
664299
  status: stats.status,
663849
664300
  totalRequests: stats.totalRequests,
663850
664301
  activeConnections: stats.activeConnections,
663851
- modelUsage: stats.modelUsage
664302
+ modelUsage: stats.modelUsage,
664303
+ tokensPerSecond: stats.tokensPerSecond
663852
664304
  });
663853
664305
  });
663854
664306
  newP2P.on("token_flash", () => statusBar.flashExposeToken());
@@ -663889,7 +664341,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
663889
664341
  status: stats.status,
663890
664342
  totalRequests: stats.totalRequests,
663891
664343
  activeConnections: stats.activeConnections,
663892
- modelUsage: stats.modelUsage
664344
+ modelUsage: stats.modelUsage,
664345
+ tokensPerSecond: stats.tokensPerSecond
663893
664346
  });
663894
664347
  });
663895
664348
  newTunnel.on("token_flash", () => statusBar.flashExposeToken());
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.149",
3
+ "version": "1.0.150",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.149",
9
+ "version": "1.0.150",
10
10
  "bundleDependencies": [
11
11
  "image-to-ascii"
12
12
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.149",
3
+ "version": "1.0.150",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",