open-agents-ai 0.105.2 → 0.105.4

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 +174 -66
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -12303,6 +12303,49 @@ function writeResp(id, result) {
12303
12303
  try { writeFileSync(respFile, JSON.stringify({ id, ...result }, null, 2)); } catch {}
12304
12304
  }
12305
12305
 
12306
+ // Collect CPU/GPU/memory metrics for piggybacking on inference responses.
12307
+ // Avoids separate invoke_capability round-trip that clogs the IPC.
12308
+ var _sysMetricsCache = null;
12309
+ var _sysMetricsCacheTs = 0;
12310
+ async function _collectSysMetrics() {
12311
+ // Cache for 5s \u2014 nvidia-smi is expensive, inference can fire rapidly
12312
+ var now = Date.now();
12313
+ if (_sysMetricsCache && (now - _sysMetricsCacheTs) < 5000) return _sysMetricsCache;
12314
+ try {
12315
+ var os = await import('node:os');
12316
+ var loads = os.loadavg();
12317
+ var cores = os.cpus().length;
12318
+ var totalMem = os.totalmem();
12319
+ var freeMem = os.freemem();
12320
+ var usedMem = totalMem - freeMem;
12321
+ var cpuModel = '';
12322
+ try { var cpuArr = os.cpus(); if (cpuArr.length > 0) cpuModel = cpuArr[0].model || ''; } catch {}
12323
+ var gpuInfo = { available: false, name: '', utilization: 0, vramUsedMB: 0, vramTotalMB: 0, vramUtilization: 0 };
12324
+ try {
12325
+ var cp = await import('node:child_process');
12326
+ 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 });
12327
+ var smiLine = smiOut.trim().split('\\n')[0];
12328
+ if (smiLine) {
12329
+ var sp = smiLine.split(',').map(function(s) { return s.trim(); });
12330
+ gpuInfo.available = true;
12331
+ gpuInfo.utilization = parseInt(sp[0] || '0', 10) || 0;
12332
+ gpuInfo.vramUsedMB = parseInt(sp[1] || '0', 10) || 0;
12333
+ gpuInfo.vramTotalMB = parseInt(sp[2] || '0', 10) || 0;
12334
+ gpuInfo.name = sp[3] || '';
12335
+ gpuInfo.vramUtilization = gpuInfo.vramTotalMB > 0 ? Math.round((gpuInfo.vramUsedMB / gpuInfo.vramTotalMB) * 100) : 0;
12336
+ }
12337
+ } catch {}
12338
+ _sysMetricsCache = {
12339
+ cpu: { utilization: Math.min(100, Math.round((loads[0] / cores) * 100)), cores: cores, model: cpuModel },
12340
+ 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 },
12341
+ gpu: gpuInfo,
12342
+ timestamp: new Date().toISOString(),
12343
+ };
12344
+ _sysMetricsCacheTs = now;
12345
+ return _sysMetricsCache;
12346
+ } catch { return null; }
12347
+ }
12348
+
12306
12349
  async function handleCmd(cmd) {
12307
12350
  const { id, action, args } = cmd;
12308
12351
  dlog('handleCmd: action=' + action + ' id=' + id);
@@ -12684,7 +12727,7 @@ async function handleCmd(cmd) {
12684
12727
  riTokenContent += tkn;
12685
12728
  appendFileSync(riStreamFile, JSON.stringify({ type: 'token', content: tkn }) + '\\n');
12686
12729
  } else if (riEvt.event === 'result' && riEvt.data) {
12687
- // Final metadata event \u2014 parse for usage/tool_calls
12730
+ // Final metadata event \u2014 parse for usage/tool_calls/system
12688
12731
  try {
12689
12732
  var riMeta = typeof riEvt.data === 'string' ? JSON.parse(riEvt.data) : riEvt.data;
12690
12733
  if (riMeta.usage) {
@@ -12694,6 +12737,8 @@ async function handleCmd(cmd) {
12694
12737
  if (riMeta.choices && riMeta.choices[0] && riMeta.choices[0].message && riMeta.choices[0].message.tool_calls) {
12695
12738
  riToolCalls = riMeta.choices[0].message.tool_calls;
12696
12739
  }
12740
+ // Pass through provider system metrics
12741
+ if (riMeta.system) var riSystemMetrics = riMeta.system;
12697
12742
  } catch {}
12698
12743
  }
12699
12744
  }
@@ -12712,8 +12757,13 @@ async function handleCmd(cmd) {
12712
12757
  },
12713
12758
  }],
12714
12759
  usage: { input_tokens: riInputTokens, output_tokens: riOutputTokens },
12760
+ system: typeof riSystemMetrics !== 'undefined' ? riSystemMetrics : undefined,
12715
12761
  };
12716
12762
  appendFileSync(riStreamFile, JSON.stringify({ type: 'done', result: JSON.stringify(riFinalPayload) }) + '\\n');
12763
+ // Write piggybacked system metrics to file for status bar
12764
+ if (typeof riSystemMetrics !== 'undefined' && riSystemMetrics) {
12765
+ try { writeFileSync(join(nexusDir, 'remote-metrics.json'), JSON.stringify({ ts: Date.now(), data: riSystemMetrics })); } catch {}
12766
+ }
12717
12767
  dlog('remote_infer: stream complete, tokens=' + riTokenContent.length + ' in=' + riInputTokens + ' out=' + riOutputTokens);
12718
12768
  break;
12719
12769
  }
@@ -12746,6 +12796,13 @@ async function handleCmd(cmd) {
12746
12796
  result: riResult,
12747
12797
  };
12748
12798
  writeResp(id, { ok: true, output: JSON.stringify(riOutput, null, 2) });
12799
+ // Write piggybacked system metrics to file for status bar (avoids IPC invoke)
12800
+ try {
12801
+ var riParsedForSys = typeof riResult === 'string' ? JSON.parse(riResult) : riResult;
12802
+ if (riParsedForSys && riParsedForSys.system) {
12803
+ writeFileSync(join(nexusDir, 'remote-metrics.json'), JSON.stringify({ ts: Date.now(), data: riParsedForSys.system }));
12804
+ }
12805
+ } catch {}
12749
12806
  }
12750
12807
  break;
12751
12808
  }
@@ -13346,6 +13403,13 @@ async function handleCmd(cmd) {
13346
13403
  };
13347
13404
  }
13348
13405
 
13406
+ // Attach system metrics to response \u2014 clients get CPU/GPU/RAM
13407
+ // for free without a separate invoke_capability round-trip
13408
+ try {
13409
+ var _sm = await _collectSysMetrics();
13410
+ if (_sm) responsePayload.system = _sm;
13411
+ } catch {}
13412
+
13349
13413
  // Stream result back
13350
13414
  await swrite({
13351
13415
  type: 'invoke.event', version: 1,
@@ -21479,6 +21543,9 @@ var init_nexusBackend = __esm({
21479
21543
  consecutiveFailures = 0;
21480
21544
  static MAX_CONSECUTIVE_FAILURES = 3;
21481
21545
  thinking;
21546
+ /** System metrics piggybacked on inference responses from the provider */
21547
+ lastSystemMetrics = null;
21548
+ lastSystemMetricsTs = 0;
21482
21549
  constructor(sendFn, model, targetPeer, authKey, thinking) {
21483
21550
  this.sendFn = sendFn;
21484
21551
  this.model = model;
@@ -21561,6 +21628,10 @@ var init_nexusBackend = __esm({
21561
21628
  if (!responseData) {
21562
21629
  throw new Error("No response data from remote inference");
21563
21630
  }
21631
+ if (responseData.system && typeof responseData.system === "object") {
21632
+ this.lastSystemMetrics = responseData.system;
21633
+ this.lastSystemMetricsTs = Date.now();
21634
+ }
21564
21635
  const choices = responseData.choices;
21565
21636
  if (choices && Array.isArray(choices)) {
21566
21637
  return {
@@ -21679,6 +21750,10 @@ var init_nexusBackend = __esm({
21679
21750
  }
21680
21751
  }
21681
21752
  }
21753
+ if (responseData?.system && typeof responseData.system === "object") {
21754
+ this.lastSystemMetrics = responseData.system;
21755
+ this.lastSystemMetricsTs = Date.now();
21756
+ }
21682
21757
  const content = responseData ? responseData.response || "" : "";
21683
21758
  if (content) {
21684
21759
  const words = content.split(/(\s+)/);
@@ -21781,6 +21856,10 @@ var init_nexusBackend = __esm({
21781
21856
  }
21782
21857
  };
21783
21858
  }
21859
+ if (r.system && typeof r.system === "object") {
21860
+ this.lastSystemMetrics = r.system;
21861
+ this.lastSystemMetricsTs = Date.now();
21862
+ }
21784
21863
  } catch {
21785
21864
  }
21786
21865
  }
@@ -29958,14 +30037,6 @@ ${this.formatConnectionInfo()}`);
29958
30037
  lines.push(`\x1B]52;c;${b64}\x07`);
29959
30038
  lines.push(` ${c2.dim("(copied to clipboard)")}`);
29960
30039
  }
29961
- const infCaps = this._capabilities.filter((cap) => cap.startsWith("inference:"));
29962
- if (infCaps.length > 0) {
29963
- lines.push("");
29964
- lines.push(` ${c2.bold("Exposed capabilities:")}`);
29965
- for (const cap of infCaps) {
29966
- lines.push(` ${c2.cyan(cap)}`);
29967
- }
29968
- }
29969
30040
  return lines.join("\n");
29970
30041
  }
29971
30042
  /** Format usage stats for display */
@@ -31395,7 +31466,7 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
31395
31466
  async function fetchPeerModels(peerId, authKey) {
31396
31467
  try {
31397
31468
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
31398
- const { existsSync: existsSync45, readFileSync: readFileSync32 } = await import("node:fs");
31469
+ const { existsSync: existsSync45, readFileSync: readFileSync33 } = await import("node:fs");
31399
31470
  const { join: join57 } = await import("node:path");
31400
31471
  const cwd4 = process.cwd();
31401
31472
  const nexusTool = new NexusTool2(cwd4);
@@ -31404,7 +31475,7 @@ async function fetchPeerModels(peerId, authKey) {
31404
31475
  try {
31405
31476
  const statusPath = join57(nexusDir, "status.json");
31406
31477
  if (existsSync45(statusPath)) {
31407
- const status = JSON.parse(readFileSync32(statusPath, "utf8"));
31478
+ const status = JSON.parse(readFileSync33(statusPath, "utf8"));
31408
31479
  if (status.peerId === peerId)
31409
31480
  isLocalPeer = true;
31410
31481
  }
@@ -31414,7 +31485,7 @@ async function fetchPeerModels(peerId, authKey) {
31414
31485
  const pricingPath = join57(nexusDir, "pricing.json");
31415
31486
  if (existsSync45(pricingPath)) {
31416
31487
  try {
31417
- const pricing = JSON.parse(readFileSync32(pricingPath, "utf8"));
31488
+ const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
31418
31489
  const localModels = (pricing.models || []).map((m) => ({
31419
31490
  name: m.model || "unknown",
31420
31491
  size: m.parameterSize || "",
@@ -31431,7 +31502,7 @@ async function fetchPeerModels(peerId, authKey) {
31431
31502
  const cachePath = join57(nexusDir, "peer-models-cache.json");
31432
31503
  if (existsSync45(cachePath)) {
31433
31504
  try {
31434
- const cache4 = JSON.parse(readFileSync32(cachePath, "utf8"));
31505
+ const cache4 = JSON.parse(readFileSync33(cachePath, "utf8"));
31435
31506
  if (cache4.peerId === peerId && cache4.models?.length > 0) {
31436
31507
  const age = Date.now() - new Date(cache4.cachedAt).getTime();
31437
31508
  if (age < 5 * 60 * 1e3) {
@@ -31549,7 +31620,7 @@ async function fetchPeerModels(peerId, authKey) {
31549
31620
  const pricingPath = join57(nexusDir, "pricing.json");
31550
31621
  if (existsSync45(pricingPath)) {
31551
31622
  try {
31552
- const pricing = JSON.parse(readFileSync32(pricingPath, "utf8"));
31623
+ const pricing = JSON.parse(readFileSync33(pricingPath, "utf8"));
31553
31624
  return (pricing.models || []).map((m) => ({
31554
31625
  name: m.model || "unknown",
31555
31626
  size: m.parameterSize || "",
@@ -47768,6 +47839,7 @@ var init_system_metrics = __esm({
47768
47839
  });
47769
47840
 
47770
47841
  // packages/cli/dist/tui/status-bar.js
47842
+ import { readFileSync as readFileSync31 } from "node:fs";
47771
47843
  var EXPERT_TOOL_BASELINES, CONTEXT_SWITCH_OVERHEAD, TURN_PLANNING_OVERHEAD, DEFAULT_TOOL_BASELINE, CODE_READ_CHARS_PER_SEC, PROSE_READ_CHARS_PER_SEC, MIN_CONTENT_FOR_READING, CODE_CONTENT_TOOLS, PROSE_CONTENT_TOOLS, HumanSpeedTracker, StatusBar;
47772
47844
  var init_status_bar = __esm({
47773
47845
  "packages/cli/dist/tui/status-bar.js"() {
@@ -48327,7 +48399,7 @@ var init_status_bar = __esm({
48327
48399
  * Queries the remote peer's system_metrics capability for CPU/GPU data,
48328
48400
  * with fallback to local metering data.
48329
48401
  */
48330
- startPeerMetricsPolling(sendCommand, peerId, authKey) {
48402
+ startPeerMetricsPolling(sendCommand, peerId, authKey, nexusDir) {
48331
48403
  this.stopRemoteMetricsPolling();
48332
48404
  this._metricsCollector.startRemote((m) => {
48333
48405
  this._unifiedMetrics = m;
@@ -48393,56 +48465,92 @@ var init_status_bar = __esm({
48393
48465
  return null;
48394
48466
  };
48395
48467
  let lastPeerMetricsDebug = "";
48468
+ let pollInFlight = false;
48396
48469
  const poll = async () => {
48397
- pollAttempt++;
48470
+ if (pollInFlight)
48471
+ return;
48472
+ pollInFlight = true;
48398
48473
  try {
48399
- const queryData = { type: "query" };
48400
- if (authKey)
48401
- queryData.auth_key = authKey;
48402
- const raw = await sendCommand("invoke_capability", {
48403
- target_peer: peerId,
48404
- capability: "system_metrics",
48405
- input: queryData
48406
- }, 6e4);
48407
- if (typeof raw === "string" && raw.startsWith("Invoke error:")) {
48408
- lastPeerMetricsDebug = `invoke error: ${raw.slice(0, 200)}`;
48409
- throw new Error(raw);
48410
- }
48411
- const metricsData = extractMetrics(raw);
48412
- if (metricsData?.cpu) {
48413
- lastPeerMetricsDebug = `ok: cpu=${metricsData.cpu.utilization}%`;
48414
- this.setRemoteMetrics({
48415
- cpuUtil: metricsData.cpu?.utilization ?? 0,
48416
- cpuCores: metricsData.cpu?.cores ?? 0,
48417
- cpuModel: metricsData.cpu?.model ?? "",
48418
- gpuUtil: metricsData.gpu?.available ? metricsData.gpu.utilization ?? 0 : -1,
48419
- gpuName: metricsData.gpu?.name ?? "",
48420
- vramUtil: metricsData.gpu?.available ? metricsData.gpu.vramUtilization ?? 0 : -1,
48421
- vramUsedMB: metricsData.gpu?.vramUsedMB ?? 0,
48422
- vramTotalMB: metricsData.gpu?.vramTotalMB ?? 0,
48423
- memUtil: metricsData.memory?.utilization ?? 0,
48424
- memTotalGB: metricsData.memory?.totalGB ?? 0,
48425
- memUsedGB: metricsData.memory?.usedGB ?? 0
48426
- });
48427
- return;
48474
+ pollAttempt++;
48475
+ if (nexusDir) {
48476
+ try {
48477
+ const metricsPath = nexusDir + "/remote-metrics.json";
48478
+ const raw = readFileSync31(metricsPath, "utf8");
48479
+ const cached = JSON.parse(raw);
48480
+ if (cached && cached.ts && Date.now() - cached.ts < 3e4) {
48481
+ const m = cached.data;
48482
+ if (m?.cpu) {
48483
+ lastPeerMetricsDebug = `ok(piggyback): cpu=${m.cpu?.utilization}%`;
48484
+ this.setRemoteMetrics({
48485
+ cpuUtil: m.cpu?.utilization ?? 0,
48486
+ cpuCores: m.cpu?.cores ?? 0,
48487
+ cpuModel: m.cpu?.model ?? "",
48488
+ gpuUtil: m.gpu?.available ? m.gpu.utilization ?? 0 : -1,
48489
+ gpuName: m.gpu?.name ?? "",
48490
+ vramUtil: m.gpu?.available ? m.gpu.vramUtilization ?? 0 : -1,
48491
+ vramUsedMB: m.gpu?.vramUsedMB ?? 0,
48492
+ vramTotalMB: m.gpu?.vramTotalMB ?? 0,
48493
+ memUtil: m.memory?.utilization ?? 0,
48494
+ memTotalGB: m.memory?.totalGB ?? 0,
48495
+ memUsedGB: m.memory?.usedGB ?? 0
48496
+ });
48497
+ return;
48498
+ }
48499
+ }
48500
+ } catch {
48501
+ }
48428
48502
  }
48429
- lastPeerMetricsDebug = `parse fail: ${typeof raw === "string" ? raw.slice(0, 300) : "non-string"}`;
48430
- } catch (e) {
48431
- if (!lastPeerMetricsDebug.startsWith("invoke error:")) {
48432
- lastPeerMetricsDebug = `exception: ${e instanceof Error ? e.message.slice(0, 200) : String(e).slice(0, 200)}`;
48503
+ try {
48504
+ const queryData = { type: "query" };
48505
+ if (authKey)
48506
+ queryData.auth_key = authKey;
48507
+ const raw = await sendCommand("invoke_capability", {
48508
+ target_peer: peerId,
48509
+ capability: "system_metrics",
48510
+ input: queryData
48511
+ }, 15e3);
48512
+ if (typeof raw === "string" && raw.startsWith("Invoke error:")) {
48513
+ lastPeerMetricsDebug = `invoke error: ${raw.slice(0, 200)}`;
48514
+ throw new Error(raw);
48515
+ }
48516
+ const metricsData = extractMetrics(raw);
48517
+ if (metricsData?.cpu) {
48518
+ lastPeerMetricsDebug = `ok: cpu=${metricsData.cpu.utilization}%`;
48519
+ this.setRemoteMetrics({
48520
+ cpuUtil: metricsData.cpu?.utilization ?? 0,
48521
+ cpuCores: metricsData.cpu?.cores ?? 0,
48522
+ cpuModel: metricsData.cpu?.model ?? "",
48523
+ gpuUtil: metricsData.gpu?.available ? metricsData.gpu.utilization ?? 0 : -1,
48524
+ gpuName: metricsData.gpu?.name ?? "",
48525
+ vramUtil: metricsData.gpu?.available ? metricsData.gpu.vramUtilization ?? 0 : -1,
48526
+ vramUsedMB: metricsData.gpu?.vramUsedMB ?? 0,
48527
+ vramTotalMB: metricsData.gpu?.vramTotalMB ?? 0,
48528
+ memUtil: metricsData.memory?.utilization ?? 0,
48529
+ memTotalGB: metricsData.memory?.totalGB ?? 0,
48530
+ memUsedGB: metricsData.memory?.usedGB ?? 0
48531
+ });
48532
+ return;
48533
+ }
48534
+ lastPeerMetricsDebug = `parse fail: ${typeof raw === "string" ? raw.slice(0, 300) : "non-string"}`;
48535
+ } catch (e) {
48536
+ if (!lastPeerMetricsDebug.startsWith("invoke error:")) {
48537
+ lastPeerMetricsDebug = `exception: ${e instanceof Error ? e.message.slice(0, 200) : String(e).slice(0, 200)}`;
48538
+ }
48433
48539
  }
48540
+ this.setRemoteMetrics({
48541
+ cpuUtil: -1,
48542
+ // -1 = unavailable (won't render bar)
48543
+ gpuUtil: -1,
48544
+ gpuName: pollAttempt <= 5 ? "connecting..." : `peer (${lastPeerMetricsDebug.slice(0, 40)})`,
48545
+ vramUtil: -1,
48546
+ memUtil: -1
48547
+ });
48548
+ } finally {
48549
+ pollInFlight = false;
48434
48550
  }
48435
- this.setRemoteMetrics({
48436
- cpuUtil: -1,
48437
- // -1 = unavailable (won't render bar)
48438
- gpuUtil: -1,
48439
- gpuName: pollAttempt <= 5 ? "connecting..." : `peer (${lastPeerMetricsDebug.slice(0, 40)})`,
48440
- vramUtil: -1,
48441
- memUtil: -1
48442
- });
48443
48551
  };
48444
- setTimeout(poll, 1e3);
48445
- this._remoteMetricsTimer = setInterval(poll, 5e3);
48552
+ setTimeout(poll, 2e3);
48553
+ this._remoteMetricsTimer = setInterval(poll, 1e4);
48446
48554
  }
48447
48555
  /** Stop polling remote metrics and switch back to local */
48448
48556
  stopRemoteMetricsPolling() {
@@ -49280,7 +49388,7 @@ import { cwd } from "node:process";
49280
49388
  import { resolve as resolve29, join as join52, dirname as dirname18, extname as extname10 } from "node:path";
49281
49389
  import { createRequire as createRequire2 } from "node:module";
49282
49390
  import { fileURLToPath as fileURLToPath12 } from "node:url";
49283
- import { readFileSync as readFileSync31, writeFileSync as writeFileSync18, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
49391
+ import { readFileSync as readFileSync32, writeFileSync as writeFileSync18, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
49284
49392
  import { existsSync as existsSync43 } from "node:fs";
49285
49393
  import { homedir as homedir13 } from "node:os";
49286
49394
  function formatTimeAgo(date) {
@@ -49521,7 +49629,7 @@ function gatherMemorySnippets(root) {
49521
49629
  continue;
49522
49630
  try {
49523
49631
  for (const f of readdirSync16(dir).filter((f2) => f2.endsWith(".json"))) {
49524
- const data = JSON.parse(readFileSync31(join52(dir, f), "utf-8"));
49632
+ const data = JSON.parse(readFileSync32(join52(dir, f), "utf-8"));
49525
49633
  for (const val of Object.values(data)) {
49526
49634
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
49527
49635
  if (v.length > 10)
@@ -50700,7 +50808,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50700
50808
  let savedHistory = [];
50701
50809
  try {
50702
50810
  if (existsSync43(HISTORY_FILE)) {
50703
- const raw = readFileSync31(HISTORY_FILE, "utf8").trim();
50811
+ const raw = readFileSync32(HISTORY_FILE, "utf8").trim();
50704
50812
  if (raw)
50705
50813
  savedHistory = raw.split("\n").reverse();
50706
50814
  }
@@ -50722,7 +50830,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50722
50830
  mkdirSync19(HISTORY_DIR, { recursive: true });
50723
50831
  appendFileSync4(HISTORY_FILE, line + "\n", "utf8");
50724
50832
  if (Math.random() < 0.02) {
50725
- const all = readFileSync31(HISTORY_FILE, "utf8").trim().split("\n");
50833
+ const all = readFileSync32(HISTORY_FILE, "utf8").trim().split("\n");
50726
50834
  if (all.length > MAX_HISTORY_LINES) {
50727
50835
  writeFileSync18(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
50728
50836
  }
@@ -50961,7 +51069,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50961
51069
  await new Promise((r) => setTimeout(r, 2e3));
50962
51070
  } catch {
50963
51071
  }
50964
- statusBar.startPeerMetricsPolling(nexusTool.sendCommand.bind(nexusTool), peerId, currentConfig.apiKey);
51072
+ statusBar.startPeerMetricsPolling(nexusTool.sendCommand.bind(nexusTool), peerId, currentConfig.apiKey, nexusTool.getNexusDir());
50965
51073
  } else if (isRemote) {
50966
51074
  statusBar.startRemoteMetricsPolling(currentConfig.backendUrl, currentConfig.apiKey);
50967
51075
  }
@@ -51104,7 +51212,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
51104
51212
  if (isPeer) {
51105
51213
  const peerId = url.slice(7);
51106
51214
  const nexusTool = new NexusTool(repoRoot);
51107
- statusBar.startPeerMetricsPolling(nexusTool.sendCommand.bind(nexusTool), peerId, apiKey);
51215
+ statusBar.startPeerMetricsPolling(nexusTool.sendCommand.bind(nexusTool), peerId, apiKey, nexusTool.getNexusDir());
51108
51216
  } else if (isRemote) {
51109
51217
  statusBar.startRemoteMetricsPolling(url, apiKey);
51110
51218
  } else {
@@ -52413,7 +52521,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
52413
52521
  if (isImage) {
52414
52522
  try {
52415
52523
  const imgPath = resolve29(repoRoot, cleanPath);
52416
- const imgBuffer = readFileSync31(imgPath);
52524
+ const imgBuffer = readFileSync32(imgPath);
52417
52525
  const base64 = imgBuffer.toString("base64");
52418
52526
  const ext = extname10(cleanPath).toLowerCase();
52419
52527
  const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.105.2",
3
+ "version": "0.105.4",
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",