open-agents-ai 0.104.16 → 0.104.18

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.
Files changed (2) hide show
  1. package/dist/index.js +194 -70
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -28374,7 +28374,7 @@ import { EventEmitter as EventEmitter3 } from "node:events";
28374
28374
  import { randomBytes as randomBytes7 } from "node:crypto";
28375
28375
  import { URL as URL2 } from "node:url";
28376
28376
  import { loadavg, cpus, totalmem, freemem } from "node:os";
28377
- import { existsSync as existsSync27, readFileSync as readFileSync19, writeFileSync as writeFileSync9, unlinkSync as unlinkSync3, mkdirSync as mkdirSync9, readdirSync as readdirSync7 } from "node:fs";
28377
+ import { existsSync as existsSync27, readFileSync as readFileSync19, writeFileSync as writeFileSync9, unlinkSync as unlinkSync3, mkdirSync as mkdirSync9, readdirSync as readdirSync7, statSync as statSync9 } from "node:fs";
28378
28378
  import { join as join35 } from "node:path";
28379
28379
  function cleanForwardHeaders(raw, targetHost) {
28380
28380
  const out = {};
@@ -29267,6 +29267,9 @@ ${this.formatConnectionInfo()}`);
29267
29267
  _loadbalance = false;
29268
29268
  _endpointAuth;
29269
29269
  _pollTimer = null;
29270
+ _activityPollTimer = null;
29271
+ _prevInvocCount = 0;
29272
+ _nexusDir = null;
29270
29273
  _stats = {
29271
29274
  status: "standby",
29272
29275
  totalRequests: 0,
@@ -29388,6 +29391,14 @@ ${this.formatConnectionInfo()}`);
29388
29391
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
29389
29392
  });
29390
29393
  }
29394
+ try {
29395
+ const invocDir = join35(nexusDir, "invocations");
29396
+ if (existsSync27(invocDir)) {
29397
+ this._prevInvocCount = readdirSync7(invocDir).filter((f) => f.endsWith(".json")).length;
29398
+ this._stats.totalRequests = this._prevInvocCount;
29399
+ }
29400
+ } catch {
29401
+ }
29391
29402
  this.startMeteringPoll(nexusDir);
29392
29403
  return this._peerId ?? "connected (peer ID pending)";
29393
29404
  }
@@ -29465,7 +29476,52 @@ ${this.formatConnectionInfo()}`);
29465
29476
  /** Poll the daemon's metering.jsonl and status.json for stats */
29466
29477
  startMeteringPoll(nexusDir) {
29467
29478
  this.stopMeteringPoll();
29479
+ this._nexusDir = nexusDir;
29468
29480
  let lastMeteringSize = 0;
29481
+ let lastMeteringLineCount = 0;
29482
+ this._activityPollTimer = setInterval(() => {
29483
+ try {
29484
+ const invocDir = join35(nexusDir, "invocations");
29485
+ if (!existsSync27(invocDir))
29486
+ return;
29487
+ const files = readdirSync7(invocDir).filter((f) => f.endsWith(".json"));
29488
+ const invocCount = files.length;
29489
+ const newRequests = invocCount - this._prevInvocCount;
29490
+ if (newRequests > 0) {
29491
+ this._stats.activeConnections = Math.max(1, newRequests);
29492
+ this._stats.totalRequests = invocCount;
29493
+ this._prevInvocCount = invocCount;
29494
+ this.emitStats();
29495
+ return;
29496
+ }
29497
+ const now = Date.now();
29498
+ let recentActive = 0;
29499
+ for (const f of files.slice(-10)) {
29500
+ try {
29501
+ const st = statSync9(join35(invocDir, f));
29502
+ if (now - st.mtimeMs < 1e4)
29503
+ recentActive++;
29504
+ } catch {
29505
+ }
29506
+ }
29507
+ const meteringFile = join35(nexusDir, "metering.jsonl");
29508
+ let meteringLines = lastMeteringLineCount;
29509
+ try {
29510
+ if (existsSync27(meteringFile)) {
29511
+ const content = readFileSync19(meteringFile, "utf8");
29512
+ meteringLines = content.split("\n").filter((l) => l.trim()).length;
29513
+ }
29514
+ } catch {
29515
+ }
29516
+ const inFlightEstimate = Math.max(0, invocCount - meteringLines);
29517
+ const prevActive = this._stats.activeConnections;
29518
+ this._stats.activeConnections = Math.max(recentActive, Math.min(inFlightEstimate, 10));
29519
+ if (this._stats.activeConnections !== prevActive)
29520
+ this.emitStats();
29521
+ } catch {
29522
+ }
29523
+ }, 1e3);
29524
+ this._activityPollTimer.unref();
29469
29525
  this._pollTimer = setInterval(() => {
29470
29526
  try {
29471
29527
  const statusPath = join35(nexusDir, "status.json");
@@ -29485,8 +29541,8 @@ ${this.formatConnectionInfo()}`);
29485
29541
  const invocCount = files.filter((f) => f.endsWith(".json")).length;
29486
29542
  if (invocCount > this._stats.totalRequests) {
29487
29543
  this._stats.totalRequests = invocCount;
29488
- this.emitStats();
29489
29544
  }
29545
+ this._prevInvocCount = invocCount;
29490
29546
  }
29491
29547
  } catch {
29492
29548
  }
@@ -29497,6 +29553,7 @@ ${this.formatConnectionInfo()}`);
29497
29553
  if (content.length > lastMeteringSize) {
29498
29554
  const newContent = content.slice(lastMeteringSize);
29499
29555
  lastMeteringSize = content.length;
29556
+ lastMeteringLineCount = content.split("\n").filter((l) => l.trim()).length;
29500
29557
  for (const line of newContent.split("\n")) {
29501
29558
  if (!line.trim())
29502
29559
  continue;
@@ -29572,6 +29629,10 @@ ${this.formatConnectionInfo()}`);
29572
29629
  clearInterval(this._pollTimer);
29573
29630
  this._pollTimer = null;
29574
29631
  }
29632
+ if (this._activityPollTimer) {
29633
+ clearInterval(this._activityPollTimer);
29634
+ this._activityPollTimer = null;
29635
+ }
29575
29636
  }
29576
29637
  emitStats() {
29577
29638
  this.emit("stats", {
@@ -31613,7 +31674,7 @@ var init_dist6 = __esm({
31613
31674
  });
31614
31675
 
31615
31676
  // packages/cli/dist/tui/oa-directory.js
31616
- import { existsSync as existsSync30, mkdirSync as mkdirSync11, readFileSync as readFileSync22, writeFileSync as writeFileSync11, readdirSync as readdirSync8, statSync as statSync9, unlinkSync as unlinkSync4 } from "node:fs";
31677
+ import { existsSync as existsSync30, mkdirSync as mkdirSync11, readFileSync as readFileSync22, writeFileSync as writeFileSync11, readdirSync as readdirSync8, statSync as statSync10, unlinkSync as unlinkSync4 } from "node:fs";
31617
31678
  import { join as join39, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
31618
31679
  import { homedir as homedir9 } from "node:os";
31619
31680
  function initOaDirectory(repoRoot) {
@@ -31806,7 +31867,7 @@ function loadRecentSessions(repoRoot, limit = 5) {
31806
31867
  return [];
31807
31868
  try {
31808
31869
  const files = readdirSync8(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
31809
- const stat5 = statSync9(join39(historyDir, f));
31870
+ const stat5 = statSync10(join39(historyDir, f));
31810
31871
  return { file: f, mtime: stat5.mtimeMs };
31811
31872
  }).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
31812
31873
  return files.map((f) => {
@@ -34948,7 +35009,7 @@ __export(voice_exports, {
34948
35009
  registerCustomOnnxModel: () => registerCustomOnnxModel,
34949
35010
  resetNarrationContext: () => resetNarrationContext
34950
35011
  });
34951
- import { existsSync as existsSync34, mkdirSync as mkdirSync13, writeFileSync as writeFileSync13, readFileSync as readFileSync24, unlinkSync as unlinkSync6, readdirSync as readdirSync9, renameSync, statSync as statSync10 } from "node:fs";
35012
+ import { existsSync as existsSync34, mkdirSync as mkdirSync13, writeFileSync as writeFileSync13, readFileSync as readFileSync24, unlinkSync as unlinkSync6, readdirSync as readdirSync9, renameSync, statSync as statSync11 } from "node:fs";
34952
35013
  import { join as join42 } from "node:path";
34953
35014
  import { homedir as homedir11, tmpdir as tmpdir7, platform as platform2 } from "node:os";
34954
35015
  import { execSync as execSync27, spawn as nodeSpawn } from "node:child_process";
@@ -35998,7 +36059,7 @@ var init_voice = __esm({
35998
36059
  const p = join42(dir, f);
35999
36060
  let size = 0;
36000
36061
  try {
36001
- size = statSync10(p).size;
36062
+ size = statSync11(p).size;
36002
36063
  } catch {
36003
36064
  }
36004
36065
  return {
@@ -45636,7 +45697,7 @@ var init_tool_policy = __esm({
45636
45697
  });
45637
45698
 
45638
45699
  // packages/cli/dist/tui/telegram-bridge.js
45639
- import { mkdirSync as mkdirSync18, existsSync as existsSync41, unlinkSync as unlinkSync8, readdirSync as readdirSync15, statSync as statSync11 } from "node:fs";
45700
+ import { mkdirSync as mkdirSync18, existsSync as existsSync41, unlinkSync as unlinkSync8, readdirSync as readdirSync15, statSync as statSync12 } from "node:fs";
45640
45701
  import { join as join50, resolve as resolve28 } from "node:path";
45641
45702
  import { writeFile as writeFileAsync } from "node:fs/promises";
45642
45703
  function convertMarkdownToTelegramHTML(md) {
@@ -47730,22 +47791,47 @@ var init_status_bar = __esm({
47730
47791
  }
47731
47792
  /** Expose gateway status — shown after capability emojis */
47732
47793
  _expose = null;
47733
- /** Blink state for expose icon during active inference */
47794
+ /** Blink state for expose icon during active inference — router LED pattern */
47734
47795
  _exposeBlinkOn = true;
47735
47796
  _exposeBlinkTimer = null;
47797
+ /** Trail timer — keeps blinking briefly after connections drop */
47798
+ _exposeTrailTimer = null;
47799
+ /** Rolling request count for activity-based trail duration */
47800
+ _exposeRecentReqs = 0;
47801
+ _exposeLastReqCount = 0;
47736
47802
  /** Update expose gateway status */
47737
47803
  setExposeStatus(status) {
47738
47804
  this._expose = status;
47739
- if (status.activeConnections > 0 && !this._exposeBlinkTimer) {
47740
- this._exposeBlinkTimer = setInterval(() => {
47741
- this._exposeBlinkOn = !this._exposeBlinkOn;
47805
+ const newReqs = status.totalRequests - this._exposeLastReqCount;
47806
+ if (newReqs > 0) {
47807
+ this._exposeRecentReqs = Math.min(this._exposeRecentReqs + newReqs, 50);
47808
+ this._exposeLastReqCount = status.totalRequests;
47809
+ }
47810
+ if (status.activeConnections > 0) {
47811
+ if (this._exposeTrailTimer) {
47812
+ clearTimeout(this._exposeTrailTimer);
47813
+ this._exposeTrailTimer = null;
47814
+ }
47815
+ if (!this._exposeBlinkTimer) {
47816
+ this._exposeBlinkTimer = setInterval(() => {
47817
+ this._exposeBlinkOn = !this._exposeBlinkOn;
47818
+ if (this.active)
47819
+ this.renderFooterPreserveCursor();
47820
+ }, 100);
47821
+ }
47822
+ } else if (this._exposeBlinkTimer && !this._exposeTrailTimer) {
47823
+ const trailMs = Math.min(1e3 + this._exposeRecentReqs * 40, 3e3);
47824
+ this._exposeTrailTimer = setTimeout(() => {
47825
+ if (this._exposeBlinkTimer) {
47826
+ clearInterval(this._exposeBlinkTimer);
47827
+ this._exposeBlinkTimer = null;
47828
+ }
47829
+ this._exposeBlinkOn = true;
47830
+ this._exposeTrailTimer = null;
47831
+ this._exposeRecentReqs = Math.max(0, this._exposeRecentReqs - 5);
47742
47832
  if (this.active)
47743
47833
  this.renderFooterPreserveCursor();
47744
- }, 500);
47745
- } else if (status.activeConnections === 0 && this._exposeBlinkTimer) {
47746
- clearInterval(this._exposeBlinkTimer);
47747
- this._exposeBlinkTimer = null;
47748
- this._exposeBlinkOn = true;
47834
+ }, trailMs);
47749
47835
  }
47750
47836
  if (this.active)
47751
47837
  this.renderFooterPreserveCursor();
@@ -47756,8 +47842,13 @@ var init_status_bar = __esm({
47756
47842
  if (this._exposeBlinkTimer) {
47757
47843
  clearInterval(this._exposeBlinkTimer);
47758
47844
  this._exposeBlinkTimer = null;
47759
- this._exposeBlinkOn = true;
47760
47845
  }
47846
+ if (this._exposeTrailTimer) {
47847
+ clearTimeout(this._exposeTrailTimer);
47848
+ this._exposeTrailTimer = null;
47849
+ }
47850
+ this._exposeBlinkOn = true;
47851
+ this._exposeRecentReqs = 0;
47761
47852
  if (this.active)
47762
47853
  this.renderFooterPreserveCursor();
47763
47854
  }
@@ -47867,78 +47958,106 @@ var init_status_bar = __esm({
47867
47958
  if (this.active)
47868
47959
  this.renderFooterPreserveCursor();
47869
47960
  });
47870
- const poll = async () => {
47871
- try {
47872
- const queryData = { type: "query" };
47873
- if (authKey)
47874
- queryData.auth_key = authKey;
47875
- const raw = await sendCommand("invoke_capability", {
47876
- target_peer: peerId,
47877
- capability: "system_metrics",
47878
- input: queryData
47879
- }, 8e3);
47880
- let parsed = raw;
47961
+ let pollAttempt = 0;
47962
+ const extractMetrics = (raw) => {
47963
+ let obj = raw;
47964
+ for (let depth = 0; depth < 3; depth++) {
47965
+ if (typeof obj !== "string")
47966
+ break;
47881
47967
  try {
47882
- parsed = JSON.parse(parsed);
47968
+ obj = JSON.parse(obj);
47883
47969
  } catch {
47970
+ break;
47971
+ }
47972
+ }
47973
+ if (!obj || typeof obj !== "object")
47974
+ return null;
47975
+ if (obj.cpu)
47976
+ return obj;
47977
+ if (obj.result) {
47978
+ let r = obj.result;
47979
+ if (typeof r === "string") {
47980
+ try {
47981
+ r = JSON.parse(r);
47982
+ } catch {
47983
+ return null;
47984
+ }
47884
47985
  }
47885
- if (typeof parsed === "string") {
47986
+ if (r && typeof r === "object" && r.cpu)
47987
+ return r;
47988
+ }
47989
+ if (obj.data) {
47990
+ let d = obj.data;
47991
+ if (typeof d === "string") {
47886
47992
  try {
47887
- parsed = JSON.parse(parsed);
47993
+ d = JSON.parse(d);
47888
47994
  } catch {
47995
+ return null;
47889
47996
  }
47890
47997
  }
47891
- if (parsed && typeof parsed === "object") {
47892
- let metricsData = null;
47893
- if (parsed.result) {
47894
- let r = parsed.result;
47895
- if (typeof r === "string") {
47998
+ if (d && typeof d === "object" && d.cpu)
47999
+ return d;
48000
+ }
48001
+ if (Array.isArray(obj.events)) {
48002
+ for (const evt of obj.events) {
48003
+ if (evt?.data) {
48004
+ let ed = evt.data;
48005
+ if (typeof ed === "string") {
47896
48006
  try {
47897
- r = JSON.parse(r);
48007
+ ed = JSON.parse(ed);
47898
48008
  } catch {
48009
+ continue;
47899
48010
  }
47900
48011
  }
47901
- metricsData = typeof r === "object" && r?.cpu ? r : null;
47902
- }
47903
- if (!metricsData && parsed.cpu) {
47904
- metricsData = parsed;
47905
- }
47906
- if (metricsData?.cpu) {
47907
- this.setRemoteMetrics({
47908
- cpuUtil: metricsData.cpu?.utilization ?? 0,
47909
- cpuCores: metricsData.cpu?.cores ?? 0,
47910
- cpuModel: metricsData.cpu?.model ?? "",
47911
- gpuUtil: metricsData.gpu?.available ? metricsData.gpu.utilization ?? 0 : -1,
47912
- gpuName: metricsData.gpu?.name ?? "",
47913
- vramUtil: metricsData.gpu?.available ? metricsData.gpu.vramUtilization ?? 0 : -1,
47914
- vramUsedMB: metricsData.gpu?.vramUsedMB ?? 0,
47915
- vramTotalMB: metricsData.gpu?.vramTotalMB ?? 0,
47916
- memUtil: metricsData.memory?.utilization ?? 0,
47917
- memTotalGB: metricsData.memory?.totalGB ?? 0,
47918
- memUsedGB: metricsData.memory?.usedGB ?? 0
47919
- });
47920
- return;
48012
+ if (ed && typeof ed === "object" && ed.cpu)
48013
+ return ed;
47921
48014
  }
47922
48015
  }
47923
- } catch {
47924
48016
  }
48017
+ return null;
48018
+ };
48019
+ const poll = async () => {
48020
+ pollAttempt++;
47925
48021
  try {
47926
- const raw = await sendCommand("metering_status", { peer_id: peerId }, 5e3);
47927
- const result = JSON.parse(raw);
47928
- if (result.ok !== false && result.output) {
48022
+ const queryData = { type: "query" };
48023
+ if (authKey)
48024
+ queryData.auth_key = authKey;
48025
+ const raw = await sendCommand("invoke_capability", {
48026
+ target_peer: peerId,
48027
+ capability: "system_metrics",
48028
+ input: queryData
48029
+ }, 1e4);
48030
+ if (typeof raw === "string" && raw.startsWith("Invoke error:"))
48031
+ throw new Error(raw);
48032
+ const metricsData = extractMetrics(raw);
48033
+ if (metricsData?.cpu) {
47929
48034
  this.setRemoteMetrics({
47930
- cpuUtil: -1,
47931
- // -1 = unavailable (won't render bar)
47932
- gpuUtil: -1,
47933
- gpuName: "peer",
47934
- vramUtil: -1,
47935
- memUtil: -1
48035
+ cpuUtil: metricsData.cpu?.utilization ?? 0,
48036
+ cpuCores: metricsData.cpu?.cores ?? 0,
48037
+ cpuModel: metricsData.cpu?.model ?? "",
48038
+ gpuUtil: metricsData.gpu?.available ? metricsData.gpu.utilization ?? 0 : -1,
48039
+ gpuName: metricsData.gpu?.name ?? "",
48040
+ vramUtil: metricsData.gpu?.available ? metricsData.gpu.vramUtilization ?? 0 : -1,
48041
+ vramUsedMB: metricsData.gpu?.vramUsedMB ?? 0,
48042
+ vramTotalMB: metricsData.gpu?.vramTotalMB ?? 0,
48043
+ memUtil: metricsData.memory?.utilization ?? 0,
48044
+ memTotalGB: metricsData.memory?.totalGB ?? 0,
48045
+ memUsedGB: metricsData.memory?.usedGB ?? 0
47936
48046
  });
48047
+ return;
47937
48048
  }
47938
48049
  } catch {
47939
48050
  }
48051
+ this.setRemoteMetrics({
48052
+ cpuUtil: -1,
48053
+ // -1 = unavailable (won't render bar)
48054
+ gpuUtil: -1,
48055
+ gpuName: "peer",
48056
+ vramUtil: -1,
48057
+ memUtil: -1
48058
+ });
47940
48059
  };
47941
- poll();
48060
+ setTimeout(poll, 3e3);
47942
48061
  this._remoteMetricsTimer = setInterval(poll, 1e4);
47943
48062
  }
47944
48063
  /** Stop polling remote metrics and switch back to local */
@@ -50389,6 +50508,11 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50389
50508
  if (isPeer) {
50390
50509
  const peerId = currentConfig.backendUrl.slice(7);
50391
50510
  const nexusTool = new NexusTool(repoRoot);
50511
+ try {
50512
+ await nexusTool.execute({ action: "connect", agent_name: "open-agents-node", agent_type: "general" });
50513
+ await new Promise((r) => setTimeout(r, 2e3));
50514
+ } catch {
50515
+ }
50392
50516
  statusBar.startPeerMetricsPolling(nexusTool.sendCommand.bind(nexusTool), peerId, currentConfig.apiKey);
50393
50517
  } else if (isRemote) {
50394
50518
  statusBar.startRemoteMetricsPolling(currentConfig.backendUrl, currentConfig.apiKey);
@@ -52604,7 +52728,7 @@ __export(index_repo_exports, {
52604
52728
  indexRepoCommand: () => indexRepoCommand
52605
52729
  });
52606
52730
  import { resolve as resolve30 } from "node:path";
52607
- import { existsSync as existsSync43, statSync as statSync12 } from "node:fs";
52731
+ import { existsSync as existsSync43, statSync as statSync13 } from "node:fs";
52608
52732
  import { cwd as cwd2 } from "node:process";
52609
52733
  async function indexRepoCommand(opts, _config) {
52610
52734
  const repoRoot = resolve30(opts.repoPath ?? cwd2());
@@ -52614,7 +52738,7 @@ async function indexRepoCommand(opts, _config) {
52614
52738
  printError(`Path does not exist: ${repoRoot}`);
52615
52739
  process.exit(1);
52616
52740
  }
52617
- const stat5 = statSync12(repoRoot);
52741
+ const stat5 = statSync13(repoRoot);
52618
52742
  if (!stat5.isDirectory()) {
52619
52743
  printError(`Path is not a directory: ${repoRoot}`);
52620
52744
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.104.16",
3
+ "version": "0.104.18",
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",