open-agents-ai 0.187.84 → 0.187.86

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 +125 -31
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -278593,6 +278593,25 @@ var init_status_bar = __esm({
278593
278593
  _streamStartTime = 0;
278594
278594
  /** Current package version (shown in metrics row, rightmost) */
278595
278595
  _version = "";
278596
+ // ── Voice & Nexus status (for header panel display) ─────────────────
278597
+ _voiceActive = false;
278598
+ _voiceModelId = "";
278599
+ /** "disconnected" | "connecting" | "connected" */
278600
+ _nexusStatus = "disconnected";
278601
+ /** Update voice status for header display */
278602
+ setVoiceStatus(active, modelId) {
278603
+ this._voiceActive = active;
278604
+ if (modelId !== void 0)
278605
+ this._voiceModelId = modelId;
278606
+ if (this.active)
278607
+ this.refreshHeaderContent();
278608
+ }
278609
+ /** Update nexus connection status for header display */
278610
+ setNexusStatus(status) {
278611
+ this._nexusStatus = status;
278612
+ if (this.active)
278613
+ this.refreshHeaderContent();
278614
+ }
278596
278615
  // ── Header Panel System ──────────────────────────────────────────────
278597
278616
  // Extensible dual-state (N-state) header: the content row inside the
278598
278617
  // ╭│╰ box cycles between registered panels via arrow buttons.
@@ -279180,19 +279199,36 @@ var init_status_bar = __esm({
279180
279199
  this.scrollRegionTop = scrollRegionTop ?? 1;
279181
279200
  this.active = true;
279182
279201
  if (this._headerPanels.length === 0) {
279202
+ const allBtns = [
279203
+ { cmd: "help", label: " help " },
279204
+ { cmd: "voice", label: " voice " },
279205
+ { cmd: "model", label: " model " },
279206
+ { cmd: "cohere", label: " cohere " }
279207
+ ];
279183
279208
  this.registerHeaderPanel("main", (innerW) => {
279184
279209
  const verText = ` OA v${this._version}`;
279185
- const btnLabels = [" help ", " voice ", " model ", " cohere "];
279186
- const btnText = btnLabels.join(" ");
279187
- const gap = Math.max(1, innerW - verText.length - btnText.length - 4);
279210
+ let usedW = verText.length + 5;
279211
+ const fittingBtns = [];
279212
+ const overflowBtns = [];
279213
+ for (const btn of allBtns) {
279214
+ const btnW = btn.label.length + 1;
279215
+ if (usedW + btnW <= innerW) {
279216
+ fittingBtns.push(btn);
279217
+ usedW += btnW;
279218
+ } else {
279219
+ overflowBtns.push(btn);
279220
+ }
279221
+ }
279222
+ this._overflowBtns = overflowBtns;
279223
+ const gap = Math.max(1, innerW - usedW + 1);
279188
279224
  let out = `\x1B[1;38;5;${TEXT_PRIMARY}m${verText}`;
279189
279225
  out += `\x1B[38;5;${TEXT_DIM}m${" ".repeat(gap)}`;
279190
- for (const btn of btnLabels) {
279191
- out += `\x1B]8;;oa-cmd:${btn.trim()}\x07\x1B[38;5;${TEXT_DIM}m${btn}\x1B]8;;\x07 `;
279226
+ for (const btn of fittingBtns) {
279227
+ out += `\x1B]8;;oa-cmd:${btn.cmd}\x07\x1B[38;5;${TEXT_DIM}m${btn.label}\x1B]8;;\x07 `;
279192
279228
  }
279193
279229
  return out;
279194
279230
  });
279195
- this.registerHeaderPanel("systems", (_innerW) => {
279231
+ this.registerHeaderPanel("systems", (innerW) => {
279196
279232
  let out = "";
279197
279233
  if (this._agentViews.size > 1) {
279198
279234
  for (const view of this._agentViews.values()) {
@@ -279207,8 +279243,19 @@ var init_status_bar = __esm({
279207
279243
  out += `\x1B[38;5;${TEXT_DIM}m no sub-agents `;
279208
279244
  }
279209
279245
  out += `\x1B[38;5;${TEXT_DIM}m\u2502 `;
279210
- out += `\x1B]8;;oa-cmd:voice\x07\x1B[38;5;${TEXT_DIM}m voice \x1B]8;;\x07 `;
279211
- out += `\x1B]8;;oa-cmd:nexus\x07\x1B[38;5;${TEXT_DIM}m nexus \x1B]8;;\x07`;
279246
+ const voiceIcon = this._voiceActive ? `\x1B[38;5;82m\u25CF` : `\x1B[38;5;${TEXT_DIM}m\u25CB`;
279247
+ const voiceLabel = this._voiceActive ? ` ${this._voiceModelId || "voice"} ` : " voice ";
279248
+ out += `\x1B]8;;oa-cmd:voice\x07${voiceIcon}\x1B[38;5;${this._voiceActive ? 82 : TEXT_DIM}m${voiceLabel}\x1B]8;;\x07 `;
279249
+ const nexusColor = this._nexusStatus === "connected" ? 82 : this._nexusStatus === "connecting" ? 208 : 196;
279250
+ const nexusDot = this._nexusStatus === "connected" ? "\u25CF" : this._nexusStatus === "connecting" ? "\u25CF" : "\u25CB";
279251
+ out += `\x1B]8;;oa-cmd:nexus\x07\x1B[38;5;${nexusColor}m${nexusDot}\x1B[38;5;${TEXT_DIM}m nexus \x1B]8;;\x07`;
279252
+ const overflow = this._overflowBtns;
279253
+ if (overflow && overflow.length > 0) {
279254
+ out += `\x1B[38;5;${TEXT_DIM}m\u2502 `;
279255
+ for (const btn of overflow) {
279256
+ out += `\x1B]8;;oa-cmd:${btn.cmd}\x07\x1B[38;5;${TEXT_DIM}m${btn.label}\x1B]8;;\x07 `;
279257
+ }
279258
+ }
279212
279259
  return out;
279213
279260
  });
279214
279261
  }
@@ -294230,18 +294277,21 @@ async function handleUpdate(subcommand, ctx3) {
294230
294277
  }
294231
294278
  };
294232
294279
  const PROGRESS_BLOCKS = [" ", "\u2801", "\u2803", "\u2807", "\u280F", "\u281F", "\u283F", "\u28FF"];
294280
+ const BRAILLE_SPINNER = ["\u2801", "\u2803", "\u2807", "\u280F", "\u281F", "\u283F", "\u28FF", "\u28FE", "\u28FC", "\u28F8", "\u28F0", "\u28E0", "\u28C0", "\u2880"];
294233
294281
  let _installProgress = 0;
294234
294282
  let _installTotal = 10;
294235
- function renderInstallFrame(version4, _frame, statusLine) {
294283
+ let _installPhase = "";
294284
+ function renderInstallFrame(version4, frame, statusLine) {
294236
294285
  const L = layout();
294237
294286
  const cols = L.cols;
294238
- const { tuiAccent: getAccent, tuiBgSeq: getBgSeq, tuiBoxFg: getBoxFg } = (init_theme(), __toCommonJS(theme_exports));
294287
+ const { tuiAccent: getAccent, tuiBgSeq: getBgSeq, tuiBoxFg: getBoxFg, tuiTextDim: getDimColor } = (init_theme(), __toCommonJS(theme_exports));
294239
294288
  const accentColor = getAccent() < 0 ? 252 : getAccent();
294240
294289
  const boxFg = getBoxFg();
294241
294290
  const bgSeq = getBgSeq();
294242
294291
  const contentTop = L.contentTop;
294243
294292
  const contentBottom = L.contentBottom;
294244
294293
  const contentHeight = L.contentHeight;
294294
+ const isDone = statusLine === "__DONE__";
294245
294295
  let buf = "\x1B[?2026h\x1B7\x1B[?25l";
294246
294296
  for (let r2 = contentTop; r2 <= contentBottom; r2++) {
294247
294297
  buf += `\x1B[${r2};1H${bgSeq}\x1B[2K`;
@@ -294258,32 +294308,42 @@ async function handleUpdate(subcommand, ctx3) {
294258
294308
  buf += `\x1B[${boxTop + r2};${boxLeft}H${boxFg}\u2502${bgSeq}${" ".repeat(innerW)}${boxFg}\u2502`;
294259
294309
  }
294260
294310
  buf += `\x1B[${boxTop + boxH - 1};${boxLeft}H${boxFg}\u2570${"\u2500".repeat(innerW)}\u256F`;
294261
- const isDone = statusLine === "__DONE__";
294262
294311
  const label = isDone ? "INSTALLED" : "INSTALLING";
294263
294312
  const labelColor = isDone ? 82 : accentColor;
294264
- const labelCol = centerCol - Math.floor(label.length / 2);
294265
- buf += `\x1B[${boxTop + 1};${labelCol}H\x1B[1;38;5;${labelColor}m${label}\x1B[0m`;
294313
+ const spinner = isDone ? " \u2713" : ` ${BRAILLE_SPINNER[frame % BRAILLE_SPINNER.length]}`;
294314
+ const fullLabel = label + spinner;
294315
+ const labelCol = centerCol - Math.floor(fullLabel.length / 2);
294316
+ buf += `\x1B[${boxTop + 1};${labelCol}H\x1B[1;38;5;${labelColor}m${label}\x1B[0m\x1B[38;5;${labelColor}m${spinner}\x1B[0m`;
294266
294317
  const progress = isDone ? 1 : Math.min(0.95, _installProgress / Math.max(1, _installTotal));
294267
294318
  const barW = innerW - 4;
294268
- const filledCols = Math.floor(progress * barW);
294269
- let bar = "";
294270
- for (let c4 = 0; c4 < barW; c4++) {
294271
- if (c4 < filledCols) {
294272
- bar += PROGRESS_BLOCKS[PROGRESS_BLOCKS.length - 1];
294273
- } else if (c4 === filledCols) {
294274
- const subProgress = progress * barW - filledCols;
294275
- const idx = Math.floor(subProgress * (PROGRESS_BLOCKS.length - 1));
294276
- bar += PROGRESS_BLOCKS[idx] ?? " ";
294277
- } else {
294278
- bar += PROGRESS_BLOCKS[0];
294319
+ const barCol = boxLeft + 3;
294320
+ if (_installProgress === 0 && !isDone) {
294321
+ let bar = "";
294322
+ for (let c4 = 0; c4 < barW; c4++) {
294323
+ const wave = Math.sin((c4 - frame * 0.8) * 0.3);
294324
+ const idx = Math.max(0, Math.min(PROGRESS_BLOCKS.length - 1, Math.floor((wave + 1) * 0.5 * (PROGRESS_BLOCKS.length - 1))));
294325
+ bar += PROGRESS_BLOCKS[idx];
294326
+ }
294327
+ buf += `\x1B[${boxTop + 2};${barCol}H\x1B[38;5;${accentColor}m${bar}\x1B[0m`;
294328
+ } else {
294329
+ const filledCols = Math.floor(progress * barW);
294330
+ let bar = "";
294331
+ for (let c4 = 0; c4 < barW; c4++) {
294332
+ if (c4 < filledCols) {
294333
+ bar += PROGRESS_BLOCKS[PROGRESS_BLOCKS.length - 1];
294334
+ } else if (c4 === filledCols) {
294335
+ const edgeIdx = isDone ? PROGRESS_BLOCKS.length - 1 : frame % (PROGRESS_BLOCKS.length - 1) + 1;
294336
+ bar += PROGRESS_BLOCKS[edgeIdx];
294337
+ } else {
294338
+ bar += PROGRESS_BLOCKS[0];
294339
+ }
294279
294340
  }
294341
+ buf += `\x1B[${boxTop + 2};${barCol}H\x1B[38;5;${accentColor}m${bar}\x1B[0m`;
294280
294342
  }
294281
- const barCol = boxLeft + 3;
294282
- buf += `\x1B[${boxTop + 2};${barCol}H\x1B[38;5;${accentColor}m${bar}\x1B[0m`;
294283
- const statusText = isDone ? `v${version4}` : statusLine || `v${version4}`;
294343
+ const phaseText = _installPhase ? `${_installPhase}` : "";
294344
+ const statusText = isDone ? `v${version4}` : statusLine || phaseText || `v${version4}`;
294284
294345
  const statusTrunc = statusText.slice(0, innerW - 2);
294285
294346
  const sCol = centerCol - Math.floor(statusTrunc.length / 2);
294286
- const { tuiTextDim: getDimColor } = (init_theme(), __toCommonJS(theme_exports));
294287
294347
  buf += `\x1B[${boxTop + 3};${sCol}H\x1B[38;5;${getDimColor()}m${statusTrunc}\x1B[0m`;
294288
294348
  buf += `\x1B[0m\x1B8\x1B[?25h\x1B[?2026l`;
294289
294349
  process.stdout.write(buf);
@@ -294296,22 +294356,29 @@ async function handleUpdate(subcommand, ctx3) {
294296
294356
  const timer = setInterval(() => {
294297
294357
  frame++;
294298
294358
  renderInstallFrame(version4, frame, status);
294299
- }, 200);
294359
+ }, 80);
294300
294360
  return {
294301
294361
  setStatus(text) {
294302
294362
  status = text;
294303
294363
  },
294364
+ setPhase(phase) {
294365
+ _installPhase = phase;
294366
+ },
294367
+ setProgress(current, total) {
294368
+ _installProgress = current;
294369
+ _installTotal = total;
294370
+ },
294304
294371
  stop(finalText) {
294305
294372
  clearInterval(timer);
294306
294373
  unlockFooterRedraws();
294307
294374
  status = "__DONE__";
294375
+ _installProgress = _installTotal;
294308
294376
  renderInstallFrame(version4, frame, status);
294309
294377
  setTimeout(() => {
294310
294378
  status = finalText;
294311
294379
  renderInstallFrame(version4, frame + 1, finalText);
294312
294380
  }, 300);
294313
294381
  },
294314
- /** Clear the overlay content area entirely — return to normal scroll area */
294315
294382
  dismiss() {
294316
294383
  unlockFooterRedraws();
294317
294384
  clearInterval(timer);
@@ -294506,7 +294573,8 @@ async function handleUpdate(subcommand, ctx3) {
294506
294573
  const installOverlay = startInstallOverlay(targetVersion);
294507
294574
  let installError = "";
294508
294575
  _installProgress = 0;
294509
- _installTotal = 10;
294576
+ _installTotal = 20;
294577
+ _installPhase = "Preparing...";
294510
294578
  const runInstall2 = (cmd) => new Promise((resolve39) => {
294511
294579
  const child = exec4(cmd, { timeout: 18e4 }, (err, _stdout, stderr) => {
294512
294580
  if (err)
@@ -294556,7 +294624,11 @@ async function handleUpdate(subcommand, ctx3) {
294556
294624
  const sudoPrefix = needsSudo ? "sudo " : "";
294557
294625
  let primaryUpdated = false;
294558
294626
  let depsUpdated = false;
294627
+ const totalPhases = (doPackage && info ? 5 : 0) + (doDeps ? 5 : 0) + (doRebuild ? 3 : 0) + (doPython ? 3 : 0) + (doCloudflared ? 2 : 0) + (doOllama ? 2 : 0);
294628
+ let completedPhases = 0;
294629
+ installOverlay.setProgress(0, totalPhases || 1);
294559
294630
  if (doPackage && info) {
294631
+ installOverlay.setPhase("Package");
294560
294632
  installOverlay.setStatus("Installing package...");
294561
294633
  const installCmd = `${sudoPrefix}npm install -g open-agents-ai@latest --prefer-online`;
294562
294634
  let installOk = await runInstall2(installCmd);
@@ -294593,10 +294665,13 @@ async function handleUpdate(subcommand, ctx3) {
294593
294665
  renderWarning(`Try manually: ${hint}`);
294594
294666
  return;
294595
294667
  }
294668
+ completedPhases += 5;
294669
+ installOverlay.setProgress(completedPhases, totalPhases);
294596
294670
  installOverlay.setStatus(`Package installed (v${info.latestVersion})`);
294597
294671
  primaryUpdated = true;
294598
294672
  }
294599
294673
  if (doDeps) {
294674
+ installOverlay.setPhase("Dependencies");
294600
294675
  installOverlay.setStatus("Checking sub-dependencies...");
294601
294676
  try {
294602
294677
  const prefix = await execA("npm prefix -g", { timeout: 5e3 });
@@ -294654,9 +294729,12 @@ async function handleUpdate(subcommand, ctx3) {
294654
294729
  }
294655
294730
  } catch {
294656
294731
  }
294732
+ completedPhases += 5;
294733
+ installOverlay.setProgress(completedPhases, totalPhases);
294657
294734
  installOverlay.setStatus(depsUpdated ? "Dependencies updated" : "Dependencies OK");
294658
294735
  }
294659
294736
  if (doOllama) {
294737
+ installOverlay.setPhase("Ollama");
294660
294738
  installOverlay.setStatus("Updating Ollama...");
294661
294739
  try {
294662
294740
  const { updateOllama: doOllamaUpgrade } = await Promise.resolve().then(() => (init_setup(), setup_exports));
@@ -294727,18 +294805,22 @@ async function handleUpdate(subcommand, ctx3) {
294727
294805
  }
294728
294806
  }
294729
294807
  if (doRebuild) {
294808
+ installOverlay.setPhase("Native Modules");
294730
294809
  installOverlay.setStatus("Rebuilding native modules...");
294731
294810
  await new Promise((resolve39) => {
294732
294811
  const child = exec4(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () => resolve39(true));
294733
294812
  child.stdout?.resume();
294734
294813
  child.stderr?.resume();
294735
294814
  });
294815
+ completedPhases += 3;
294816
+ installOverlay.setProgress(completedPhases, totalPhases);
294736
294817
  installOverlay.setStatus("Native modules rebuilt");
294737
294818
  }
294738
294819
  const { existsSync: fsExists } = await import("node:fs");
294739
294820
  const { join: pathJoin } = await import("node:path");
294740
294821
  const { homedir: getHome } = await import("node:os");
294741
294822
  if (doPython) {
294823
+ installOverlay.setPhase("Python");
294742
294824
  let hasPython = hasCmd("python3") || hasCmd("python");
294743
294825
  if (!hasPython) {
294744
294826
  installOverlay.setStatus("Installing Python3...");
@@ -294774,9 +294856,12 @@ async function handleUpdate(subcommand, ctx3) {
294774
294856
  });
294775
294857
  installOverlay.setStatus("Python deps bootstrapped");
294776
294858
  }
294859
+ completedPhases += 3;
294860
+ installOverlay.setProgress(completedPhases, totalPhases);
294777
294861
  }
294778
294862
  let hasCf = false;
294779
294863
  if (doCloudflared) {
294864
+ installOverlay.setPhase("Cloudflared");
294780
294865
  installOverlay.setStatus("Checking cloudflared...");
294781
294866
  try {
294782
294867
  const { execSync: es } = await import("node:child_process");
@@ -309322,6 +309407,7 @@ ${opts.systemPromptAddition}` : `Working directory: ${repoRoot}`;
309322
309407
  voiceEngine.luxttsCloneRef = savedSettings.voiceCloneRef;
309323
309408
  }
309324
309409
  voiceEngine.toggle().then((msg) => {
309410
+ statusBar.setVoiceStatus(voiceEngine.enabled, voiceEngine.modelId || "");
309325
309411
  if (statusBar?.isActive && !statusBar.isStreaming) {
309326
309412
  statusBar.beginContentWrite();
309327
309413
  renderInfo(msg);
@@ -309851,13 +309937,16 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
309851
309937
  }
309852
309938
  };
309853
309939
  const _tryNexusConnect = async (attempt) => {
309940
+ statusBar.setNexusStatus("connecting");
309854
309941
  try {
309855
309942
  const r2 = await autoNexus.execute({ action: "connect" });
309856
309943
  const out = r2.output || String(r2);
309857
309944
  if (out.includes("Connected") || out.includes("Already connected")) {
309945
+ statusBar.setNexusStatus("connected");
309858
309946
  writeContent(() => renderInfo("Nexus P2P network connected."));
309859
309947
  _registerNexusDaemon();
309860
309948
  } else if (out.includes("failed") || out.includes("Error")) {
309949
+ statusBar.setNexusStatus("disconnected");
309861
309950
  if (attempt < 2) {
309862
309951
  await new Promise((r3) => setTimeout(r3, 5e3));
309863
309952
  return _tryNexusConnect(attempt + 1);
@@ -309869,13 +309958,16 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
309869
309958
  const sr = await autoNexus.execute({ action: "status" });
309870
309959
  const so = sr.output || String(sr);
309871
309960
  if (/Connected:\s*true/i.test(so)) {
309961
+ statusBar.setNexusStatus("connected");
309872
309962
  writeContent(() => renderInfo("Nexus P2P network connected."));
309873
309963
  _registerNexusDaemon();
309874
309964
  return;
309875
309965
  }
309876
309966
  }
309967
+ statusBar.setNexusStatus("disconnected");
309877
309968
  }
309878
309969
  } catch {
309970
+ statusBar.setNexusStatus("disconnected");
309879
309971
  }
309880
309972
  };
309881
309973
  _tryNexusConnect(1);
@@ -310310,6 +310402,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
310310
310402
  },
310311
310403
  async voiceToggle() {
310312
310404
  const msg = await voiceEngine.toggle();
310405
+ statusBar.setVoiceStatus(voiceEngine.enabled, voiceEngine.modelId || "");
310313
310406
  if (telegramBridge) {
310314
310407
  telegramBridge.voiceEnabled = voiceEngine.enabled;
310315
310408
  if (voiceEngine.enabled && voiceEngine.ready) {
@@ -310778,6 +310871,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
310778
310871
  if (!voiceEngine.enabled || !voiceEngine.ready) {
310779
310872
  writeContent(() => renderInfo("Auto-enabling voice for call session..."));
310780
310873
  const voiceMsg = await voiceEngine.toggle();
310874
+ statusBar.setVoiceStatus(voiceEngine.enabled, voiceEngine.modelId || "");
310781
310875
  writeContent(() => renderInfo(voiceMsg));
310782
310876
  }
310783
310877
  if (!adminSessionKey) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.84",
3
+ "version": "0.187.86",
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",