omnius 1.0.147 → 1.0.148

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
@@ -13138,6 +13138,27 @@ async function handleCmd(cmd) {
13138
13138
  var _csAvgLatency = _cohereStats.queriesAnswered > 0 ? Math.round(_cohereStats.totalLatencyMs / _cohereStats.queriesAnswered) : 0;
13139
13139
  var _csModels = Object.entries(_cohereStats.modelsUsed).sort(function(a, b) { return b[1] - a[1]; });
13140
13140
  var _csPeers = Object.entries(_cohereStats.peersServed).sort(function(a, b) { return b[1] - a[1]; });
13141
+ var _csSnapshot = {
13142
+ status: cohereActive ? 'active' : 'inactive',
13143
+ active: cohereActive,
13144
+ daemonPid: process.pid,
13145
+ uptimeSec: _csUptime,
13146
+ lastQueryAt: _cohereStats.lastQueryAt || 0,
13147
+ queriesReceived: _cohereStats.queriesReceived,
13148
+ queriesAnswered: _cohereStats.queriesAnswered,
13149
+ queriesErrors: _cohereStats.queriesErrors,
13150
+ queriesSent: _cohereStats.queriesSent,
13151
+ avgLatencyMs: _csAvgLatency,
13152
+ bytesIn: _cohereStats.bytesIn,
13153
+ bytesOut: _cohereStats.bytesOut,
13154
+ modelsUsed: _cohereStats.modelsUsed,
13155
+ peersServed: _cohereStats.peersServed,
13156
+ allowedModels: _cohereAllowedModels ? [..._cohereAllowedModels] : null
13157
+ };
13158
+ if (args.format === 'json' || args.json === true || args.json === 'true' || args.json === '1') {
13159
+ writeResp(id, { ok: true, output: JSON.stringify(_csSnapshot) });
13160
+ break;
13161
+ }
13141
13162
  var _csLines = [
13142
13163
  '═══ COHERE Network Stats ═══',
13143
13164
  '',
@@ -16549,6 +16570,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16549
16570
  max_tokens: {
16550
16571
  type: "string",
16551
16572
  description: "For remote_infer: maximum tokens to generate (e.g. '4096'). Default: 4096"
16573
+ },
16574
+ format: {
16575
+ type: "string",
16576
+ description: "For cohere_stats: set to 'json' for structured stats"
16577
+ },
16578
+ json: {
16579
+ type: "string",
16580
+ description: "For cohere_stats: set to '1' for structured stats"
16552
16581
  }
16553
16582
  },
16554
16583
  required: ["action"],
@@ -16686,7 +16715,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
16686
16715
  result = await this.sendDaemonCmd("cohere_disable", {});
16687
16716
  break;
16688
16717
  case "cohere_stats":
16689
- result = await this.sendDaemonCmd("cohere_stats", {});
16718
+ result = await this.sendDaemonCmd("cohere_stats", { format: String(args.format ?? ""), json: String(args.json ?? "") });
16690
16719
  break;
16691
16720
  case "cohere_allow_model":
16692
16721
  result = await this.sendDaemonCmd("cohere_allow_model", { model: String(args.model ?? "") });
@@ -571491,6 +571520,47 @@ var init_voice_soul = __esm({
571491
571520
  }
571492
571521
  });
571493
571522
 
571523
+ // packages/cli/src/tui/usage-bars.ts
571524
+ function formatCompactCount(value2) {
571525
+ const n2 = Math.max(0, Math.floor(Number.isFinite(value2) ? value2 : 0));
571526
+ if (n2 < 1e3) return String(n2);
571527
+ if (n2 < 1e6) return `${(n2 / 1e3).toFixed(n2 < 1e4 ? 1 : 0)}K`;
571528
+ return `${(n2 / 1e6).toFixed(n2 < 1e7 ? 1 : 0)}M`;
571529
+ }
571530
+ function formatResetDelta(resetAt, now = Date.now()) {
571531
+ if (!Number.isFinite(resetAt) || resetAt <= now) return "";
571532
+ const totalMinutes = Math.ceil((resetAt - now) / 6e4);
571533
+ if (totalMinutes < 60) return ` reset ${totalMinutes}m`;
571534
+ const hours = Math.floor(totalMinutes / 60);
571535
+ const minutes = totalMinutes % 60;
571536
+ return minutes > 0 ? ` reset ${hours}h ${minutes}m` : ` reset ${hours}h`;
571537
+ }
571538
+ function formatUsageBar(options2) {
571539
+ const total = Math.max(0, Math.floor(Number.isFinite(options2.total) ? options2.total : 0));
571540
+ const rawUsed = Math.max(0, Math.floor(Number.isFinite(options2.used) ? options2.used : 0));
571541
+ const used = total > 0 ? Math.min(total, rawUsed) : 0;
571542
+ const width = Math.max(4, options2.width ?? 18);
571543
+ const labelWidth = Math.max(options2.label.length, options2.labelWidth ?? 16);
571544
+ const pct = total > 0 ? Math.round(used / total * 100) : 0;
571545
+ const filled = total > 0 ? Math.min(width, Math.round(pct / 100 * width)) : 0;
571546
+ const color = pct >= 90 ? c3.red : pct >= 70 ? c3.yellow : c3.green;
571547
+ const bar = color("█".repeat(filled)) + c3.dim("░".repeat(width - filled));
571548
+ const reset = options2.resetAt ? c3.dim(formatResetDelta(options2.resetAt)) : "";
571549
+ return [
571550
+ c3.cyan(options2.label.padEnd(labelWidth)),
571551
+ bar,
571552
+ color(`${pct}%`.padStart(4)),
571553
+ c3.dim(`${formatCompactCount(rawUsed)}/${formatCompactCount(total)}`),
571554
+ reset
571555
+ ].join(" ").trimEnd();
571556
+ }
571557
+ var init_usage_bars = __esm({
571558
+ "packages/cli/src/tui/usage-bars.ts"() {
571559
+ "use strict";
571560
+ init_render();
571561
+ }
571562
+ });
571563
+
571494
571564
  // packages/cli/src/tui/expose.ts
571495
571565
  import { createServer as createServer5, request as httpRequest } from "node:http";
571496
571566
  import { request as httpsRequest } from "node:https";
@@ -571537,6 +571607,38 @@ function fmtTokens(n2) {
571537
571607
  if (n2 < 1e6) return `${(n2 / 1e3).toFixed(1)}K`;
571538
571608
  return `${(n2 / 1e6).toFixed(1)}M`;
571539
571609
  }
571610
+ function safeNonNegativeInt(value2) {
571611
+ const n2 = Number(value2);
571612
+ return Number.isFinite(n2) && n2 > 0 ? Math.floor(n2) : 0;
571613
+ }
571614
+ function nextSponsorDailyReset(now = Date.now()) {
571615
+ return now + SPONSOR_DAILY_WINDOW_MS;
571616
+ }
571617
+ function readSponsorUsageState(stateDir) {
571618
+ try {
571619
+ const path12 = join105(stateDir, "sponsor", SPONSOR_USAGE_FILE_NAME);
571620
+ if (!existsSync90(path12)) return null;
571621
+ const parsed = JSON.parse(readFileSync71(path12, "utf8"));
571622
+ const dailyTokensUsed = safeNonNegativeInt(parsed.dailyTokensUsed);
571623
+ const dailyTokensResetAt = safeNonNegativeInt(parsed.dailyTokensResetAt);
571624
+ if (!dailyTokensResetAt) return null;
571625
+ return {
571626
+ dailyTokensUsed,
571627
+ dailyTokensResetAt,
571628
+ updatedAt: typeof parsed.updatedAt === "string" ? parsed.updatedAt : (/* @__PURE__ */ new Date()).toISOString()
571629
+ };
571630
+ } catch {
571631
+ return null;
571632
+ }
571633
+ }
571634
+ function writeSponsorUsageState(stateDir, state) {
571635
+ try {
571636
+ const dir = join105(stateDir, "sponsor");
571637
+ mkdirSync50(dir, { recursive: true });
571638
+ writeFileSync45(join105(dir, SPONSOR_USAGE_FILE_NAME), JSON.stringify(state, null, 2));
571639
+ } catch {
571640
+ }
571641
+ }
571540
571642
  function readExposeState(stateDir) {
571541
571643
  try {
571542
571644
  const path12 = join105(stateDir, STATE_FILE_NAME);
@@ -571700,11 +571802,12 @@ function removeP2PExposeState(stateDir) {
571700
571802
  } catch {
571701
571803
  }
571702
571804
  }
571703
- var HOP_BY_HOP_HEADERS, CF_HEADERS_PREFIX, DEFAULT_EXPOSE_MAX_BODY_BYTES, INTERNAL_CAPABILITIES, DEFAULT_TARGETS, STATE_FILE_NAME, ExposeGateway, P2P_STATE_FILE_NAME, ExposeP2PGateway;
571805
+ var HOP_BY_HOP_HEADERS, CF_HEADERS_PREFIX, DEFAULT_EXPOSE_MAX_BODY_BYTES, INTERNAL_CAPABILITIES, DEFAULT_TARGETS, STATE_FILE_NAME, SPONSOR_USAGE_FILE_NAME, SPONSOR_DAILY_WINDOW_MS, SPONSOR_REQUEST_WINDOW_MS, ExposeGateway, P2P_STATE_FILE_NAME, ExposeP2PGateway;
571704
571806
  var init_expose = __esm({
571705
571807
  "packages/cli/src/tui/expose.ts"() {
571706
571808
  "use strict";
571707
571809
  init_render();
571810
+ init_usage_bars();
571708
571811
  init_typed_node_events();
571709
571812
  HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
571710
571813
  "connection",
@@ -571726,6 +571829,9 @@ var init_expose = __esm({
571726
571829
  custom: "http://127.0.0.1:11434"
571727
571830
  };
571728
571831
  STATE_FILE_NAME = "expose-state.json";
571832
+ SPONSOR_USAGE_FILE_NAME = "usage.json";
571833
+ SPONSOR_DAILY_WINDOW_MS = 864e5;
571834
+ SPONSOR_REQUEST_WINDOW_MS = 6e4;
571729
571835
  ExposeGateway = class _ExposeGateway extends EventEmitter8 {
571730
571836
  constructor(options2) {
571731
571837
  super();
@@ -571743,6 +571849,8 @@ var init_expose = __esm({
571743
571849
  } else {
571744
571850
  this._authKey = options2.authKey;
571745
571851
  }
571852
+ this.loadSponsorUsage();
571853
+ this.refreshSponsorUsageStats();
571746
571854
  }
571747
571855
  options;
571748
571856
  server = null;
@@ -571765,6 +571873,7 @@ var init_expose = __esm({
571765
571873
  _dailyTokensResetAt = 0;
571766
571874
  /** Sponsor rate limits (set via setSponsorLimits) */
571767
571875
  _sponsorLimits = null;
571876
+ _sponsorBlockedRequests = 0;
571768
571877
  _authKey;
571769
571878
  _targetUrl;
571770
571879
  _kind;
@@ -571783,7 +571892,8 @@ var init_expose = __esm({
571783
571892
  users: /* @__PURE__ */ new Map(),
571784
571893
  budgetTokensRemaining: 0,
571785
571894
  budgetTokensTotal: 0,
571786
- budgetResetAt: 0
571895
+ budgetResetAt: 0,
571896
+ sponsorUsage: null
571787
571897
  };
571788
571898
  get tunnelUrl() {
571789
571899
  return this._tunnelUrl;
@@ -571803,42 +571913,140 @@ var init_expose = __esm({
571803
571913
  /** Set sponsor rate limits — enables rate limiting middleware in the proxy */
571804
571914
  setSponsorLimits(limits) {
571805
571915
  this._sponsorLimits = limits;
571916
+ this.ensureSponsorDailyWindow();
571917
+ this.refreshSponsorUsageStats();
571918
+ this.emitStats();
571919
+ }
571920
+ getSponsorUsageSnapshot() {
571921
+ this.refreshSponsorUsageStats();
571922
+ return this._stats.sponsorUsage ? { ...this._stats.sponsorUsage } : null;
571923
+ }
571924
+ loadSponsorUsage() {
571925
+ if (!this._stateDir) {
571926
+ this._dailyTokensResetAt = nextSponsorDailyReset();
571927
+ return;
571928
+ }
571929
+ const saved = readSponsorUsageState(this._stateDir);
571930
+ if (!saved) {
571931
+ this._dailyTokensUsed = 0;
571932
+ this._dailyTokensResetAt = nextSponsorDailyReset();
571933
+ return;
571934
+ }
571935
+ const now = Date.now();
571936
+ if (saved.dailyTokensResetAt <= now) {
571937
+ this._dailyTokensUsed = 0;
571938
+ this._dailyTokensResetAt = nextSponsorDailyReset(now);
571939
+ this.saveSponsorUsage();
571940
+ } else {
571941
+ this._dailyTokensUsed = saved.dailyTokensUsed;
571942
+ this._dailyTokensResetAt = saved.dailyTokensResetAt;
571943
+ }
571944
+ }
571945
+ saveSponsorUsage() {
571946
+ if (!this._stateDir) return;
571947
+ writeSponsorUsageState(this._stateDir, {
571948
+ dailyTokensUsed: this._dailyTokensUsed,
571949
+ dailyTokensResetAt: this._dailyTokensResetAt,
571950
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
571951
+ });
571952
+ }
571953
+ ensureSponsorDailyWindow(now = Date.now()) {
571954
+ if (!this._dailyTokensResetAt || this._dailyTokensResetAt <= now) {
571955
+ this._dailyTokensUsed = 0;
571956
+ this._dailyTokensResetAt = nextSponsorDailyReset(now);
571957
+ this.saveSponsorUsage();
571958
+ }
571959
+ }
571960
+ pruneSponsorRequestWindows(now = Date.now()) {
571961
+ for (const [ip, window2] of this._rateLimitWindows.entries()) {
571962
+ while (window2.length > 0 && window2[0] < now - SPONSOR_REQUEST_WINDOW_MS) window2.shift();
571963
+ if (window2.length === 0) this._rateLimitWindows.delete(ip);
571964
+ }
571965
+ }
571966
+ sponsorRequestWindowUsage(now = Date.now()) {
571967
+ this.pruneSponsorRequestWindows(now);
571968
+ let count = 0;
571969
+ let oldest = Number.POSITIVE_INFINITY;
571970
+ for (const window2 of this._rateLimitWindows.values()) {
571971
+ count += window2.length;
571972
+ if (window2.length > 0) oldest = Math.min(oldest, window2[0]);
571973
+ }
571974
+ return {
571975
+ count,
571976
+ resetAt: Number.isFinite(oldest) ? oldest + SPONSOR_REQUEST_WINDOW_MS : now + SPONSOR_REQUEST_WINDOW_MS
571977
+ };
571978
+ }
571979
+ refreshSponsorUsageStats(now = Date.now()) {
571980
+ if (!this._sponsorLimits) {
571981
+ this._stats.sponsorUsage = null;
571982
+ return;
571983
+ }
571984
+ this.ensureSponsorDailyWindow(now);
571985
+ const req2 = this.sponsorRequestWindowUsage(now);
571986
+ this._stats.sponsorUsage = {
571987
+ enabled: true,
571988
+ transport: "tunnel",
571989
+ dailyTokensUsed: this._dailyTokensUsed,
571990
+ dailyTokensLimit: this._sponsorLimits.maxTokensPerDay,
571991
+ dailyResetAt: this._dailyTokensResetAt,
571992
+ requestsInWindow: req2.count,
571993
+ requestsPerMinuteLimit: this._sponsorLimits.maxRequestsPerMinute,
571994
+ requestWindowResetAt: req2.resetAt,
571995
+ activeConnections: this._stats.activeConnections,
571996
+ maxConcurrent: this._sponsorLimits.maxConcurrent,
571997
+ blockedRequests: this._sponsorBlockedRequests,
571998
+ allowedModels: this._sponsorLimits.allowedModels === "all" ? "all" : [...this._sponsorLimits.allowedModels]
571999
+ };
572000
+ }
572001
+ markSponsorBlocked() {
572002
+ this._sponsorBlockedRequests++;
572003
+ this.refreshSponsorUsageStats();
571806
572004
  }
571807
572005
  /** Check rate limits for a request. Returns null if OK, or error message string if blocked. */
571808
- checkRateLimit(userIp, model) {
572006
+ checkRateLimit(userIp, model, options2 = {}) {
571809
572007
  if (!this._sponsorLimits) return null;
571810
572008
  const lim = this._sponsorLimits;
572009
+ const now = Date.now();
572010
+ if (lim.maxRequestsPerMinute <= 0 || lim.maxTokensPerDay <= 0 || lim.maxConcurrent <= 0) {
572011
+ this.markSponsorBlocked();
572012
+ return "Sponsored endpoint is paused or has no quota configured.";
572013
+ }
571811
572014
  if (lim.allowedModels !== "all" && model && !lim.allowedModels.includes(model)) {
572015
+ this.markSponsorBlocked();
571812
572016
  return `Model '${model}' is not available on this sponsored endpoint. Available: ${lim.allowedModels.join(", ")}`;
571813
572017
  }
571814
- if (this._stats.activeConnections >= lim.maxConcurrent) {
572018
+ if (this._stats.activeConnections > lim.maxConcurrent) {
572019
+ this.markSponsorBlocked();
571815
572020
  return `Too many concurrent requests (${this._stats.activeConnections}/${lim.maxConcurrent}). Try again shortly.`;
571816
572021
  }
571817
- const now = Date.now();
571818
- const windowMs = 6e4;
571819
572022
  let window2 = this._rateLimitWindows.get(userIp);
571820
572023
  if (!window2) {
571821
572024
  window2 = [];
571822
572025
  this._rateLimitWindows.set(userIp, window2);
571823
572026
  }
571824
- while (window2.length > 0 && window2[0] < now - windowMs) window2.shift();
572027
+ while (window2.length > 0 && window2[0] < now - SPONSOR_REQUEST_WINDOW_MS) window2.shift();
571825
572028
  if (window2.length >= lim.maxRequestsPerMinute) {
571826
- const retryAfterMs = window2[0] + windowMs - now;
572029
+ this.markSponsorBlocked();
572030
+ const retryAfterMs = window2[0] + SPONSOR_REQUEST_WINDOW_MS - now;
571827
572031
  return `Rate limited (${lim.maxRequestsPerMinute} req/min). Retry in ${Math.ceil(retryAfterMs / 1e3)}s.`;
571828
572032
  }
571829
- window2.push(now);
571830
- if (this._dailyTokensResetAt < now) {
571831
- this._dailyTokensUsed = 0;
571832
- this._dailyTokensResetAt = now + 864e5;
571833
- }
572033
+ if (options2.commitRequest) window2.push(now);
572034
+ this.ensureSponsorDailyWindow(now);
571834
572035
  if (this._dailyTokensUsed >= lim.maxTokensPerDay) {
572036
+ this.markSponsorBlocked();
571835
572037
  return `Daily token budget exhausted (${fmtTokens(lim.maxTokensPerDay)}). Resets in ${Math.ceil((this._dailyTokensResetAt - now) / 36e5)}h.`;
571836
572038
  }
572039
+ this.refreshSponsorUsageStats(now);
571837
572040
  return null;
571838
572041
  }
571839
572042
  /** Track token usage from a completed response */
571840
572043
  trackTokenUsage(tokensIn, tokensOut) {
571841
- this._dailyTokensUsed += tokensIn + tokensOut;
572044
+ const total = safeNonNegativeInt(tokensIn) + safeNonNegativeInt(tokensOut);
572045
+ if (total <= 0) return;
572046
+ this.ensureSponsorDailyWindow();
572047
+ this._dailyTokensUsed += total;
572048
+ this.saveSponsorUsage();
572049
+ this.refreshSponsorUsageStats();
571842
572050
  }
571843
572051
  // ── Lifecycle ───────────────────────────────────────────────────────────
571844
572052
  async start() {
@@ -572047,7 +572255,7 @@ var init_expose = __esm({
572047
572255
  user.activeRequests++;
572048
572256
  user.lastSeen = Date.now();
572049
572257
  this.emitStats();
572050
- const preRateLimitCheck = this.checkRateLimit(userIp, "");
572258
+ const preRateLimitCheck = this.checkRateLimit(userIp, "", { commitRequest: false });
572051
572259
  if (preRateLimitCheck) {
572052
572260
  this._stats.activeConnections--;
572053
572261
  user.activeRequests--;
@@ -572136,8 +572344,8 @@ var init_expose = __esm({
572136
572344
  } catch {
572137
572345
  }
572138
572346
  }
572139
- if (requestModel && this._sponsorLimits) {
572140
- const modelCheck = this.checkRateLimit(userIp, requestModel);
572347
+ if (this._sponsorLimits) {
572348
+ const modelCheck = this.checkRateLimit(userIp, requestModel, { commitRequest: true });
572141
572349
  if (modelCheck) {
572142
572350
  this._stats.activeConnections--;
572143
572351
  user.activeRequests--;
@@ -572523,10 +572731,12 @@ ${this.formatConnectionInfo()}`);
572523
572731
  });
572524
572732
  }
572525
572733
  emitStats() {
572734
+ this.refreshSponsorUsageStats();
572526
572735
  this.emit("stats", {
572527
572736
  ...this._stats,
572528
572737
  modelUsage: new Map(this._stats.modelUsage),
572529
- users: new Map(this._stats.users)
572738
+ users: new Map(this._stats.users),
572739
+ sponsorUsage: this._stats.sponsorUsage ? { ...this._stats.sponsorUsage } : null
572530
572740
  });
572531
572741
  }
572532
572742
  /** Format connection info for display */
@@ -572568,6 +572778,28 @@ ${this.formatConnectionInfo()}`);
572568
572778
  const budgetColor = pct > 50 ? c3.green : pct > 20 ? c3.yellow : c3.red;
572569
572779
  lines.push(` ${c3.cyan("Budget".padEnd(18))} ${budgetColor(fmtTokens(s2.budgetTokensRemaining))}${c3.dim("/")}${fmtTokens(s2.budgetTokensTotal)} ${c3.dim(`(${pct}% left)`)}`);
572570
572780
  }
572781
+ if (s2.sponsorUsage) {
572782
+ lines.push("");
572783
+ lines.push(` ${c3.bold("Sponsor Quota")}`);
572784
+ lines.push(` ${formatUsageBar({
572785
+ label: "Daily tokens",
572786
+ used: s2.sponsorUsage.dailyTokensUsed,
572787
+ total: s2.sponsorUsage.dailyTokensLimit,
572788
+ resetAt: s2.sponsorUsage.dailyResetAt
572789
+ })}`);
572790
+ lines.push(` ${formatUsageBar({
572791
+ label: "Requests/min",
572792
+ used: s2.sponsorUsage.requestsInWindow,
572793
+ total: s2.sponsorUsage.requestsPerMinuteLimit,
572794
+ resetAt: s2.sponsorUsage.requestWindowResetAt
572795
+ })}`);
572796
+ lines.push(` ${formatUsageBar({
572797
+ label: "Concurrency",
572798
+ used: s2.sponsorUsage.activeConnections,
572799
+ total: s2.sponsorUsage.maxConcurrent
572800
+ })}`);
572801
+ lines.push(` ${c3.cyan("Blocked".padEnd(18))} ${s2.sponsorUsage.blockedRequests}`);
572802
+ }
572571
572803
  const visibleModels = Array.from(s2.modelUsage.entries()).filter(([model]) => !INTERNAL_CAPABILITIES.has(model));
572572
572804
  if (visibleModels.length > 0) {
572573
572805
  lines.push("");
@@ -572629,6 +572861,11 @@ ${this.formatConnectionInfo()}`);
572629
572861
  _passthrough = false;
572630
572862
  _loadbalance = false;
572631
572863
  _endpointAuth;
572864
+ _sponsorLimits = null;
572865
+ _sponsorBlockedRequests = 0;
572866
+ _sponsorRequestWindow = [];
572867
+ _dailyTokensUsed = 0;
572868
+ _dailyTokensResetAt = 0;
572632
572869
  _pollTimer = null;
572633
572870
  _activityPollTimer = null;
572634
572871
  /** Fast token flash timer — pulses LED at 200ms while inference is active */
@@ -572647,7 +572884,8 @@ ${this.formatConnectionInfo()}`);
572647
572884
  users: /* @__PURE__ */ new Map(),
572648
572885
  budgetTokensRemaining: 0,
572649
572886
  budgetTokensTotal: 0,
572650
- budgetResetAt: 0
572887
+ budgetResetAt: 0,
572888
+ sponsorUsage: null
572651
572889
  };
572652
572890
  get peerId() {
572653
572891
  return this._peerId;
@@ -572689,6 +572927,93 @@ ${this.formatConnectionInfo()}`);
572689
572927
  } else {
572690
572928
  this._authKey = options2.authKey;
572691
572929
  }
572930
+ this.loadSponsorUsage();
572931
+ this.refreshSponsorUsageStats();
572932
+ }
572933
+ setSponsorLimits(limits) {
572934
+ this._sponsorLimits = limits;
572935
+ this.ensureSponsorDailyWindow();
572936
+ this.refreshSponsorUsageStats();
572937
+ this.emitStats();
572938
+ }
572939
+ getSponsorUsageSnapshot() {
572940
+ this.refreshSponsorUsageStats();
572941
+ return this._stats.sponsorUsage ? { ...this._stats.sponsorUsage } : null;
572942
+ }
572943
+ loadSponsorUsage() {
572944
+ if (!this._stateDir) {
572945
+ this._dailyTokensResetAt = nextSponsorDailyReset();
572946
+ return;
572947
+ }
572948
+ const saved = readSponsorUsageState(this._stateDir);
572949
+ if (!saved) {
572950
+ this._dailyTokensUsed = 0;
572951
+ this._dailyTokensResetAt = nextSponsorDailyReset();
572952
+ return;
572953
+ }
572954
+ const now = Date.now();
572955
+ if (saved.dailyTokensResetAt <= now) {
572956
+ this._dailyTokensUsed = 0;
572957
+ this._dailyTokensResetAt = nextSponsorDailyReset(now);
572958
+ this.saveSponsorUsage();
572959
+ } else {
572960
+ this._dailyTokensUsed = saved.dailyTokensUsed;
572961
+ this._dailyTokensResetAt = saved.dailyTokensResetAt;
572962
+ }
572963
+ }
572964
+ saveSponsorUsage() {
572965
+ if (!this._stateDir) return;
572966
+ writeSponsorUsageState(this._stateDir, {
572967
+ dailyTokensUsed: this._dailyTokensUsed,
572968
+ dailyTokensResetAt: this._dailyTokensResetAt,
572969
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
572970
+ });
572971
+ }
572972
+ ensureSponsorDailyWindow(now = Date.now()) {
572973
+ if (!this._dailyTokensResetAt || this._dailyTokensResetAt <= now) {
572974
+ this._dailyTokensUsed = 0;
572975
+ this._dailyTokensResetAt = nextSponsorDailyReset(now);
572976
+ this.saveSponsorUsage();
572977
+ }
572978
+ }
572979
+ recordSponsorRequest(now = Date.now()) {
572980
+ this._sponsorRequestWindow.push(now);
572981
+ this.pruneSponsorRequestWindow(now);
572982
+ }
572983
+ pruneSponsorRequestWindow(now = Date.now()) {
572984
+ while (this._sponsorRequestWindow.length > 0 && this._sponsorRequestWindow[0] < now - SPONSOR_REQUEST_WINDOW_MS) {
572985
+ this._sponsorRequestWindow.shift();
572986
+ }
572987
+ }
572988
+ trackTokenUsage(tokensIn, tokensOut) {
572989
+ const total = safeNonNegativeInt(tokensIn) + safeNonNegativeInt(tokensOut);
572990
+ if (total <= 0) return;
572991
+ this.ensureSponsorDailyWindow();
572992
+ this._dailyTokensUsed += total;
572993
+ this.saveSponsorUsage();
572994
+ this.refreshSponsorUsageStats();
572995
+ }
572996
+ refreshSponsorUsageStats(now = Date.now()) {
572997
+ if (!this._sponsorLimits) {
572998
+ this._stats.sponsorUsage = null;
572999
+ return;
573000
+ }
573001
+ this.ensureSponsorDailyWindow(now);
573002
+ this.pruneSponsorRequestWindow(now);
573003
+ this._stats.sponsorUsage = {
573004
+ enabled: true,
573005
+ transport: "libp2p",
573006
+ dailyTokensUsed: this._dailyTokensUsed,
573007
+ dailyTokensLimit: this._sponsorLimits.maxTokensPerDay,
573008
+ dailyResetAt: this._dailyTokensResetAt,
573009
+ requestsInWindow: this._sponsorRequestWindow.length,
573010
+ requestsPerMinuteLimit: this._sponsorLimits.maxRequestsPerMinute,
573011
+ requestWindowResetAt: this._sponsorRequestWindow[0] ? this._sponsorRequestWindow[0] + SPONSOR_REQUEST_WINDOW_MS : now + SPONSOR_REQUEST_WINDOW_MS,
573012
+ activeConnections: this._stats.activeConnections,
573013
+ maxConcurrent: this._sponsorLimits.maxConcurrent,
573014
+ blockedRequests: this._sponsorBlockedRequests,
573015
+ allowedModels: this._sponsorLimits.allowedModels === "all" ? "all" : [...this._sponsorLimits.allowedModels]
573016
+ };
572692
573017
  }
572693
573018
  async start() {
572694
573019
  this._onInfo?.("Connecting to nexus P2P network...");
@@ -572947,6 +573272,8 @@ ${this.formatConnectionInfo()}`);
572947
573272
  }
572948
573273
  this._stats.totalTokensIn += tokIn;
572949
573274
  this._stats.totalTokensOut += tokOut;
573275
+ this.recordSponsorRequest();
573276
+ this.trackTokenUsage(tokIn, tokOut);
572950
573277
  const peerId = record.from || record.peerId || "unknown";
572951
573278
  const shortPeer = peerId.length > 16 ? peerId.slice(0, 16) + "..." : peerId;
572952
573279
  let user = this._stats.users.get(shortPeer);
@@ -573010,10 +573337,12 @@ ${this.formatConnectionInfo()}`);
573010
573337
  }
573011
573338
  }
573012
573339
  emitStats() {
573340
+ this.refreshSponsorUsageStats();
573013
573341
  this.emit("stats", {
573014
573342
  ...this._stats,
573015
573343
  modelUsage: new Map(this._stats.modelUsage),
573016
- users: new Map(this._stats.users)
573344
+ users: new Map(this._stats.users),
573345
+ sponsorUsage: this._stats.sponsorUsage ? { ...this._stats.sponsorUsage } : null
573017
573346
  });
573018
573347
  }
573019
573348
  /** Format connection info for display */
@@ -573061,6 +573390,28 @@ ${this.formatConnectionInfo()}`);
573061
573390
  const budgetColor = pct > 50 ? c3.green : pct > 20 ? c3.yellow : c3.red;
573062
573391
  lines.push(` ${c3.cyan("Budget".padEnd(18))} ${budgetColor(fmtTokens(s2.budgetTokensRemaining))}${c3.dim("/")}${fmtTokens(s2.budgetTokensTotal)} ${c3.dim(`(${pct}% left)`)}`);
573063
573392
  }
573393
+ if (s2.sponsorUsage) {
573394
+ lines.push("");
573395
+ lines.push(` ${c3.bold("Sponsor Quota")}`);
573396
+ lines.push(` ${formatUsageBar({
573397
+ label: "Daily tokens",
573398
+ used: s2.sponsorUsage.dailyTokensUsed,
573399
+ total: s2.sponsorUsage.dailyTokensLimit,
573400
+ resetAt: s2.sponsorUsage.dailyResetAt
573401
+ })}`);
573402
+ lines.push(` ${formatUsageBar({
573403
+ label: "Requests/min",
573404
+ used: s2.sponsorUsage.requestsInWindow,
573405
+ total: s2.sponsorUsage.requestsPerMinuteLimit,
573406
+ resetAt: s2.sponsorUsage.requestWindowResetAt
573407
+ })}`);
573408
+ lines.push(` ${formatUsageBar({
573409
+ label: "Concurrency",
573410
+ used: s2.sponsorUsage.activeConnections,
573411
+ total: s2.sponsorUsage.maxConcurrent
573412
+ })}`);
573413
+ lines.push(` ${c3.cyan("Blocked".padEnd(18))} ${s2.sponsorUsage.blockedRequests}`);
573414
+ }
573064
573415
  const visibleModels = Array.from(s2.modelUsage.entries()).filter(([model]) => !INTERNAL_CAPABILITIES.has(model));
573065
573416
  if (visibleModels.length > 0) {
573066
573417
  lines.push("");
@@ -590733,15 +591084,52 @@ async function stepReview(config, rl, availableRows) {
590733
591084
  if (!result.confirmed || result.key === "cancel") return false;
590734
591085
  return result.key === "go_live";
590735
591086
  }
590736
- async function showSponsorDashboard(config, projectDir2, rl, availableRows) {
591087
+ async function showSponsorDashboard(config, projectDir2, rl, availableRows, sponsorUsage) {
590737
591088
  const isPaused = config.status === "paused";
590738
591089
  const enabledEps = config.endpoints.filter((e2) => e2.enabled);
591090
+ const dailyTokensLimit = sponsorUsage?.dailyTokensLimit || config.rateLimits.maxTokensPerDay;
591091
+ const requestsPerMinuteLimit = sponsorUsage?.requestsPerMinuteLimit || config.rateLimits.maxRequestsPerMinute;
591092
+ const maxConcurrent = sponsorUsage?.maxConcurrent || config.rateLimits.maxConcurrent;
591093
+ const usageItems = [
591094
+ {
591095
+ key: "info_usage_daily",
591096
+ label: ` ${formatUsageBar({
591097
+ label: "Daily tokens",
591098
+ used: sponsorUsage?.dailyTokensUsed ?? 0,
591099
+ total: dailyTokensLimit,
591100
+ resetAt: sponsorUsage?.dailyResetAt
591101
+ })}`
591102
+ },
591103
+ {
591104
+ key: "info_usage_rpm",
591105
+ label: ` ${formatUsageBar({
591106
+ label: "Requests/min",
591107
+ used: sponsorUsage?.requestsInWindow ?? 0,
591108
+ total: requestsPerMinuteLimit,
591109
+ resetAt: sponsorUsage?.requestWindowResetAt
591110
+ })}`
591111
+ },
591112
+ {
591113
+ key: "info_usage_concurrent",
591114
+ label: ` ${formatUsageBar({
591115
+ label: "Concurrency",
591116
+ used: sponsorUsage?.activeConnections ?? 0,
591117
+ total: maxConcurrent
591118
+ })}`
591119
+ },
591120
+ {
591121
+ key: "info_usage_blocked",
591122
+ label: ` Blocked: ${sponsorUsage?.blockedRequests ?? 0}`
591123
+ }
591124
+ ];
590739
591125
  const items = [
590740
591126
  { key: "hdr", label: "Sponsor Dashboard" },
590741
591127
  { key: "info_status", label: ` Status: ${isPaused ? "● PAUSED" : "● ACTIVE"}` },
590742
591128
  { key: "info_ep", label: ` Endpoints: ${enabledEps.map((e2) => e2.label).join(", ")}` },
590743
591129
  { key: "info_transport", label: ` Transport: ${[config.transport.cloudflared ? "Cloudflared" : "", config.transport.libp2p ? "libp2p" : ""].filter(Boolean).join(" + ")}` },
590744
591130
  { key: "info_limits", label: ` Limits: ${config.rateLimits.maxRequestsPerMinute} req/min, ${config.rateLimits.maxTokensPerDay.toLocaleString()} tokens/day` },
591131
+ { key: "info_usage_hdr", label: " Usage" },
591132
+ ...usageItems,
590745
591133
  { key: "sep", label: "" },
590746
591134
  { key: "modify", label: " [Modify Settings]" },
590747
591135
  { key: isPaused ? "resume" : "pause", label: isPaused ? " [Resume Sponsorship]" : " [Pause Sponsorship]" },
@@ -590751,7 +591139,7 @@ async function showSponsorDashboard(config, projectDir2, rl, availableRows) {
590751
591139
  items,
590752
591140
  title: "Sponsor Dashboard",
590753
591141
  rl,
590754
- skipKeys: ["hdr", "sep", "info_status", "info_ep", "info_transport", "info_limits"],
591142
+ 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"],
590755
591143
  availableRows
590756
591144
  });
590757
591145
  if (!result.confirmed) return "close";
@@ -590816,6 +591204,7 @@ var init_sponsor_wizard = __esm({
590816
591204
  init_dist();
590817
591205
  init_tui_select();
590818
591206
  init_render();
591207
+ init_usage_bars();
590819
591208
  }
590820
591209
  });
590821
591210
 
@@ -595102,6 +595491,17 @@ function stopSponsorHeartbeat() {
595102
595491
  }
595103
595492
  _lastRegisteredSponsorPayload = null;
595104
595493
  }
595494
+ function sponsorUsageFromGateway(gateway) {
595495
+ if (!gateway) return null;
595496
+ try {
595497
+ if (typeof gateway.getSponsorUsageSnapshot === "function") {
595498
+ return gateway.getSponsorUsageSnapshot();
595499
+ }
595500
+ return gateway.stats?.sponsorUsage ?? null;
595501
+ } catch {
595502
+ return null;
595503
+ }
595504
+ }
595105
595505
  function registerCommandHelp2(items) {
595106
595506
  registerCommandHelp(items);
595107
595507
  }
@@ -598581,6 +598981,10 @@ The session corrections MUST become hard rules in the SKILL.md Rules section.`;
598581
598981
  return "handled";
598582
598982
  }
598583
598983
  case "cohere": {
598984
+ if (arg === "status" || arg === "stats") {
598985
+ await showCohereStatus(ctx3);
598986
+ return "handled";
598987
+ }
598584
598988
  await showCohereDashboard(ctx3);
598585
598989
  return "handled";
598586
598990
  }
@@ -599324,11 +599728,16 @@ sleep 1
599324
599728
  renderInfo("No active sponsorship. Run /sponsor to start.");
599325
599729
  return "handled";
599326
599730
  }
599731
+ const dashboardGw = ctx3.getExposeGateway?.();
599732
+ if (existingConfig.status === "active" && dashboardGw && "setSponsorLimits" in dashboardGw) {
599733
+ dashboardGw.setSponsorLimits(existingConfig.rateLimits);
599734
+ }
599327
599735
  const action = await showSponsorDashboard2(
599328
599736
  existingConfig,
599329
599737
  projectDir2,
599330
599738
  sponsorRl,
599331
- ctx3.availableContentRows?.()
599739
+ ctx3.availableContentRows?.(),
599740
+ sponsorUsageFromGateway(dashboardGw)
599332
599741
  );
599333
599742
  switch (action) {
599334
599743
  case "modify":
@@ -599355,6 +599764,9 @@ sleep 1
599355
599764
  existingConfig.status = "active";
599356
599765
  saveSponsorConfig2(projectDir2, existingConfig);
599357
599766
  const resumeGw = ctx3.getExposeGateway?.();
599767
+ if (resumeGw && "setSponsorLimits" in resumeGw) {
599768
+ resumeGw.setSponsorLimits(existingConfig.rateLimits);
599769
+ }
599358
599770
  if (resumeGw?.tunnelUrl) {
599359
599771
  const resumePayload = {
599360
599772
  name: existingConfig.header?.message || "Omnius Sponsor",
@@ -603263,15 +603675,65 @@ async function showHelpMenu(ctx3) {
603263
603675
  }
603264
603676
  }
603265
603677
  }
603266
- async function showCohereDashboard(ctx3) {
603267
- const isActive = ctx3.isCohere?.() ?? false;
603268
- let stats = {
603678
+ function emptyCohereStats(isActive = false) {
603679
+ return {
603680
+ status: isActive ? "active" : "inactive",
603681
+ active: isActive,
603682
+ daemonPid: 0,
603683
+ uptimeSec: 0,
603684
+ lastQueryAt: 0,
603685
+ queriesReceived: 0,
603269
603686
  queriesAnswered: 0,
603687
+ queriesErrors: 0,
603270
603688
  queriesSent: 0,
603271
- insightsShared: 0,
603272
- peersConnected: 0
603689
+ avgLatencyMs: 0,
603690
+ bytesIn: 0,
603691
+ bytesOut: 0,
603692
+ modelsUsed: {},
603693
+ peersServed: {},
603694
+ allowedModels: null
603273
603695
  };
603274
- let modelList = [];
603696
+ }
603697
+ function numberField(value2) {
603698
+ const n2 = Number(value2);
603699
+ return Number.isFinite(n2) && n2 > 0 ? Math.floor(n2) : 0;
603700
+ }
603701
+ function mapNumberRecord(value2) {
603702
+ if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) return {};
603703
+ const out = {};
603704
+ for (const [key, raw] of Object.entries(value2)) {
603705
+ out[key] = numberField(raw);
603706
+ }
603707
+ return out;
603708
+ }
603709
+ function parseCohereStatsOutput(output, isActive = false) {
603710
+ try {
603711
+ const parsed = JSON.parse(output);
603712
+ const active = typeof parsed.active === "boolean" ? parsed.active : String(parsed.status ?? "").toLowerCase() === "active";
603713
+ return {
603714
+ status: active ? "active" : "inactive",
603715
+ active,
603716
+ daemonPid: numberField(parsed.daemonPid),
603717
+ uptimeSec: numberField(parsed.uptimeSec),
603718
+ lastQueryAt: numberField(parsed.lastQueryAt),
603719
+ queriesReceived: numberField(parsed.queriesReceived),
603720
+ queriesAnswered: numberField(parsed.queriesAnswered),
603721
+ queriesErrors: numberField(parsed.queriesErrors),
603722
+ queriesSent: numberField(parsed.queriesSent),
603723
+ avgLatencyMs: numberField(parsed.avgLatencyMs),
603724
+ bytesIn: numberField(parsed.bytesIn),
603725
+ bytesOut: numberField(parsed.bytesOut),
603726
+ modelsUsed: mapNumberRecord(parsed.modelsUsed),
603727
+ peersServed: mapNumberRecord(parsed.peersServed),
603728
+ allowedModels: Array.isArray(parsed.allowedModels) ? parsed.allowedModels.map(String) : null
603729
+ };
603730
+ } catch {
603731
+ return emptyCohereStats(isActive);
603732
+ }
603733
+ }
603734
+ async function fetchCohereDashboardState(ctx3) {
603735
+ const isActive = ctx3.isCohere?.() ?? false;
603736
+ const state = { stats: emptyCohereStats(isActive), modelList: [] };
603275
603737
  try {
603276
603738
  const nexus = new NexusTool(ctx3.repoRoot);
603277
603739
  try {
@@ -603283,29 +603745,52 @@ async function showCohereDashboard(ctx3) {
603283
603745
  } catch {
603284
603746
  }
603285
603747
  try {
603286
- const r2 = await nexus.execute({ action: "cohere_stats" });
603287
- if (r2.success) {
603288
- try {
603289
- const d2 = JSON.parse(r2.output);
603290
- Object.assign(stats, d2);
603291
- } catch {
603292
- }
603293
- }
603748
+ const r2 = await nexus.execute({ action: "cohere_stats", format: "json" });
603749
+ if (r2.success) state.stats = parseCohereStatsOutput(r2.output, isActive);
603294
603750
  } catch {
603295
603751
  }
603296
603752
  try {
603297
603753
  const r2 = await nexus.execute({ action: "cohere_list_models" });
603298
603754
  if (r2.success) {
603299
603755
  try {
603300
- modelList = JSON.parse(r2.output).models || [];
603756
+ state.modelList = JSON.parse(r2.output).models || [];
603301
603757
  } catch {
603302
- modelList = r2.output.split("\n").filter((l2) => l2.trim());
603758
+ state.modelList = r2.output.split("\n").map((l2) => l2.trim()).filter(Boolean);
603303
603759
  }
603304
603760
  }
603305
603761
  } catch {
603306
603762
  }
603307
603763
  } catch {
603308
603764
  }
603765
+ return state;
603766
+ }
603767
+ function cohereStatusLines(stats, modelList) {
603768
+ const modelEntries = Object.entries(stats.modelsUsed).sort((a2, b) => b[1] - a2[1]);
603769
+ const peerEntries = Object.entries(stats.peersServed).sort((a2, b) => b[1] - a2[1]);
603770
+ const uptime2 = stats.uptimeSec < 60 ? `${stats.uptimeSec}s` : stats.uptimeSec < 3600 ? `${Math.floor(stats.uptimeSec / 60)}m ${stats.uptimeSec % 60}s` : `${Math.floor(stats.uptimeSec / 3600)}h ${Math.floor(stats.uptimeSec % 3600 / 60)}m`;
603771
+ return [
603772
+ c3.bold("COHERE Status"),
603773
+ `Status: ${stats.active ? c3.green("ACTIVE") : c3.dim("inactive")}`,
603774
+ `Daemon: ${stats.daemonPid ? `pid ${stats.daemonPid}` : "not connected"} · uptime ${uptime2}`,
603775
+ `Last query: ${stats.lastQueryAt ? new Date(stats.lastQueryAt).toISOString() : "never"}`,
603776
+ "",
603777
+ formatUsageBar({ label: "Answered", used: stats.queriesAnswered, total: Math.max(1, stats.queriesReceived), width: 18 }),
603778
+ formatUsageBar({ label: "Errors", used: stats.queriesErrors, total: Math.max(1, stats.queriesReceived), width: 18 }),
603779
+ `Sent out: ${stats.queriesSent} · avg latency ${stats.avgLatencyMs}ms`,
603780
+ `Data: in ${formatFileSize(stats.bytesIn)} · out ${formatFileSize(stats.bytesOut)}`,
603781
+ "",
603782
+ `Models exposed: ${modelList.length}`,
603783
+ `Allowlist: ${stats.allowedModels ? stats.allowedModels.join(", ") || "(empty)" : "all downloaded models"}`,
603784
+ `Top models: ${modelEntries.length ? modelEntries.slice(0, 5).map(([m2, n2]) => `${m2} (${n2})`).join(", ") : "none yet"}`,
603785
+ `Peers served: ${peerEntries.length ? peerEntries.slice(0, 5).map(([p2, n2]) => `${p2.slice(0, 20)} (${n2})`).join(", ") : "none yet"}`
603786
+ ];
603787
+ }
603788
+ async function showCohereStatus(ctx3) {
603789
+ const { stats, modelList } = await fetchCohereDashboardState(ctx3);
603790
+ safeLog(cohereStatusLines(stats, modelList).join("\n"));
603791
+ }
603792
+ async function showCohereDashboard(ctx3) {
603793
+ let { stats, modelList } = await fetchCohereDashboardState(ctx3);
603309
603794
  while (true) {
603310
603795
  const currentActive = ctx3.isCohere?.() ?? false;
603311
603796
  const toggleLabel = currentActive ? "Disable COHERE" : "Enable COHERE";
@@ -603322,7 +603807,7 @@ async function showCohereDashboard(ctx3) {
603322
603807
  {
603323
603808
  key: "stats",
603324
603809
  label: "Network Stats",
603325
- detail: `${stats.queriesAnswered} answered · ${stats.queriesSent} sent · ${stats.insightsShared} shared`
603810
+ detail: `${stats.queriesAnswered} answered · ${stats.queriesSent} sent · ${stats.queriesErrors} errors`
603326
603811
  },
603327
603812
  {
603328
603813
  key: "identity",
@@ -603375,11 +603860,11 @@ async function showCohereDashboard(ctx3) {
603375
603860
  },
603376
603861
  {
603377
603862
  key: "insights",
603378
- label: `Insights shared: ${c3.bold(String(stats.insightsShared || 0))}`
603863
+ label: `Avg latency: ${c3.bold(String(stats.avgLatencyMs || 0))}ms`
603379
603864
  },
603380
603865
  {
603381
603866
  key: "peers",
603382
- label: `Peers connected: ${c3.bold(String(stats.peersConnected || 0))}`
603867
+ label: `Peers served: ${c3.bold(String(Object.keys(stats.peersServed || {}).length))}`
603383
603868
  },
603384
603869
  { key: "hdr2", label: selectColors.dim("─── Actions ───") },
603385
603870
  {
@@ -603397,17 +603882,9 @@ async function showCohereDashboard(ctx3) {
603397
603882
  availableRows: ctx3.availableContentRows?.()
603398
603883
  });
603399
603884
  if (statResult.key === "refresh") {
603400
- try {
603401
- const nexus = new NexusTool(ctx3.repoRoot);
603402
- const r2 = await nexus.execute({ action: "cohere_stats" });
603403
- if (r2.success) {
603404
- try {
603405
- Object.assign(stats, JSON.parse(r2.output));
603406
- } catch {
603407
- }
603408
- }
603409
- } catch {
603410
- }
603885
+ const refreshed = await fetchCohereDashboardState(ctx3);
603886
+ stats = refreshed.stats;
603887
+ modelList = refreshed.modelList;
603411
603888
  }
603412
603889
  continue;
603413
603890
  }
@@ -607773,6 +608250,7 @@ var init_commands = __esm({
607773
608250
  init_listen();
607774
608251
  init_dist();
607775
608252
  init_tui_select();
608253
+ init_usage_bars();
607776
608254
  init_overlay_lock();
607777
608255
  init_drop_panel();
607778
608256
  init_memory_menu();
@@ -617483,6 +617961,13 @@ function senderKey2(entry) {
617483
617961
  if (entry.role === "assistant") return entry.username || entry.speaker || "assistant";
617484
617962
  return String(entry.fromUserId || entry.username || entry.firstName || senderLabel(entry));
617485
617963
  }
617964
+ function speakerRole(entry) {
617965
+ if (entry.role === "assistant") return "agent_self";
617966
+ return entry.isBot ? "participant_bot" : "participant_human";
617967
+ }
617968
+ function identityBoundary(entry) {
617969
+ return speakerRole(entry) === "agent_self" ? "this message is authored by the Telegram agent itself" : "this message is authored by another Telegram participant; first-person claims belong to that participant, not the agent";
617970
+ }
617486
617971
  function scopeFor(entry, options2) {
617487
617972
  const chatType = entry.chatType || options2.chatType || "unknown";
617488
617973
  return {
@@ -617496,7 +617981,7 @@ function senderFor(entry) {
617496
617981
  id: senderKey2(entry),
617497
617982
  username: entry.username,
617498
617983
  displayName: senderLabel(entry),
617499
- isBot: entry.role === "assistant"
617984
+ isBot: entry.role === "assistant" || entry.isBot === true
617500
617985
  };
617501
617986
  }
617502
617987
  function messageIdFor(entry, sessionKey) {
@@ -617535,7 +618020,11 @@ function contentFor(entry, sessionKey, options2) {
617535
618020
  `message_id: ${messageIdFor(entry, sessionKey)}`,
617536
618021
  entry.messageThreadId != null ? `thread_id: ${entry.messageThreadId}` : "",
617537
618022
  entry.replyToMessageId != null ? `reply_to_message_id: ${entry.replyToMessageId}` : "",
618023
+ `actor_key: ${senderKey2(entry)}`,
617538
618024
  `speaker: ${senderLabel(entry)}`,
618025
+ `speaker_role: ${speakerRole(entry)}`,
618026
+ `identity_boundary: ${identityBoundary(entry)}`,
618027
+ entry.replyContext?.sender ? `reply_sender: ${entry.replyContext.sender.username || entry.replyContext.sender.firstName || entry.replyContext.sender.id || "unknown"} [${entry.replyContext.sender.isBot ? "participant_bot" : "participant_human"}]` : "",
617539
618028
  entry.mode ? `mode: ${entry.mode}` : "",
617540
618029
  entry.mediaSummary ? `media: ${compact(entry.mediaSummary, 260)}` : "",
617541
618030
  "",
@@ -617559,7 +618048,11 @@ function metadataFor(entry, sessionKey, options2) {
617559
618048
  username: entry.username,
617560
618049
  firstName: entry.firstName,
617561
618050
  fromUserId: entry.fromUserId,
618051
+ isBot: entry.isBot,
617562
618052
  speaker: senderLabel(entry),
618053
+ actorKey: senderKey2(entry),
618054
+ speakerRole: speakerRole(entry),
618055
+ identityBoundary: identityBoundary(entry),
617563
618056
  mediaSummary: entry.mediaSummary
617564
618057
  }
617565
618058
  };
@@ -617810,12 +618303,14 @@ function episodeLine(episode) {
617810
618303
  const meta = episode.metadata;
617811
618304
  const telegram = meta?.telegram;
617812
618305
  const speaker = clean4(telegram?.speaker || telegram?.username || "unknown", 80);
618306
+ const role = clean4(telegram?.speakerRole || "participant_human", 40);
617813
618307
  const messageId = telegram?.messageId == null ? "unknown" : String(telegram.messageId);
617814
618308
  const replyTo = telegram?.replyToMessageId == null ? "" : ` reply_to=${telegram.replyToMessageId}`;
617815
618309
  return [
617816
618310
  `episode_id=${episode.id}`,
617817
618311
  `message_id=${messageId}${replyTo}`,
617818
618312
  `speaker=${speaker}`,
618313
+ `speaker_role=${role}`,
617819
618314
  `modality=${episode.modality}`,
617820
618315
  `content=${clean4(episode.content, 700)}`
617821
618316
  ].join(" | ");
@@ -617836,6 +618331,9 @@ function buildTelegramReflectionExtractionPrompt(options2) {
617836
618331
  "- Use only the scoped Telegram corpus, graph nodes, graph edges, and source anchors below.",
617837
618332
  "- Preserve message_id and episode_id anchors on every item when possible.",
617838
618333
  "- Do not infer identity from a face, voice, or name unless the corpus explicitly says it.",
618334
+ "- speaker_role=agent_self is the Telegram agent; speaker_role=participant_human or participant_bot is another chat participant.",
618335
+ "- Do not assign participant first-person claims, preferences, names, or self-descriptions to the agent/self unless the source episode has speaker_role=agent_self.",
618336
+ "- Replies between non-agent participants are social context and relationship evidence, not direct agent self-reflection.",
617839
618337
  "- Private DM followups may be proposed but must not be framed as already sent.",
617840
618338
  "- same_group followups must be concise, low-intrusion, and anchored to a source message id.",
617841
618339
  "- If a category has no evidence, return an empty array for that category.",
@@ -618253,6 +618751,8 @@ function formatTelegramSocialStateContext(state, input) {
618253
618751
  const replyKey = input.replySender ? telegramSocialActorKey(input.replySender) : void 0;
618254
618752
  const thread = state.threads[telegramSocialThreadKey(input)];
618255
618753
  const participant = state.participants[senderKey3];
618754
+ const senderIdentity = selfKey && senderKey3 === selfKey ? "agent_self" : "participant";
618755
+ const replyIdentity = replyKey ? selfKey && replyKey === selfKey ? "agent_self" : "participant" : "none";
618256
618756
  const relevantKeys = new Set([senderKey3, selfKey, replyKey].filter(Boolean));
618257
618757
  const edges = state.relationships.filter((edge) => relevantKeys.has(edge.fromKey) || relevantKeys.has(edge.toKey)).sort((a2, b) => b.lastSeenAt - a2.lastSeenAt).slice(0, limit);
618258
618758
  const outcomes = state.outcomes.filter((outcome) => outcome.senderKey === senderKey3 || outcome.chatId === String(input.chatId)).sort((a2, b) => b.ts - a2.ts).slice(0, limit);
@@ -618261,6 +618761,8 @@ function formatTelegramSocialStateContext(state, input) {
618261
618761
  const preferences = preferenceLines(state.preferences[senderKey3]);
618262
618762
  return [
618263
618763
  "### Telegram Structured Social State",
618764
+ selfKey ? `Agent self node: ${selfKey}` : "Agent self node: unknown",
618765
+ `Identity boundary: the agent is the self node only. Current actor ${senderKey3} is ${senderIdentity}; reply target ${replyKey ?? "none"} is ${replyIdentity}. Participant first-person claims belong to their actor node, not the agent, unless that actor is the self node.`,
618264
618766
  `Current actor node: ${senderKey3} [${participant?.actorKind || telegramSocialActorKind(input)}] messages=${participant?.messageCount ?? 0}${participant?.lastText ? ` last=${jsonLine(participant.lastText, 140)}` : ""}`,
618265
618767
  thread ? `Active channel/thread: ${thread.key}; messages=${thread.messageCount}; participants=${thread.participantKeys.slice(-8).join(", ") || "none"}; last_outcomes=${thread.lastOutcomeIds.slice(-5).join(", ") || "none"}` : "",
618266
618768
  preferences.length ? `Relevant preference vector for ${senderKey3}:
@@ -624918,6 +625420,7 @@ ${lines.join("\n")}`);
624918
625420
  "Classify the live scenario by inference from the full context. Do not use a fixed taxonomy, keyword list, or preset scenario enum.",
624919
625421
  "Create a situation-specific scenario_id and scenario_label, then summarize the active state loop that should govern the later attention decision.",
624920
625422
  "Use the persona docs below as binding behavioral guidance.",
625423
+ "Maintain the Telegram identity boundary: the agent is only the bot/self actor. Other users and peer bots replying to each other are participants; their first-person claims are not the agent's identity or self-reflection.",
624921
625424
  "Return JSON only. No markdown. No <think> tags.",
624922
625425
  "",
624923
625426
  'Schema: {"silent_disposition":"what happens silently with this message","mental_note":"concise observation of the turn","memory_note":"what scoped memory should retain or connect","relationship_note":"relationship/thread implication","procedure_note":"active tree/branch/abort implication","voice_note":"final voice implication if a reply happens","scenario_note":"identified scenario and transition state","scenario_id":"dynamic inferred scenario id","scenario_label":"human readable dynamic scenario label","scenario_confidence":0.0-1.0,"scenario_objective":"current scenario objective","scenario_state_loop":"state loop to maintain until transition"}',
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.147",
3
+ "version": "1.0.148",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.147",
9
+ "version": "1.0.148",
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.147",
3
+ "version": "1.0.148",
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",