open-agents-ai 0.104.18 → 0.104.19

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 +124 -36
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -28954,6 +28954,8 @@ var init_expose = __esm({
28954
28954
  if (responseTail.length > 2048) {
28955
28955
  responseTail = responseTail.slice(-2048);
28956
28956
  }
28957
+ if (isStreaming)
28958
+ this.emit("token_flash");
28957
28959
  });
28958
28960
  if (isStreaming) {
28959
28961
  if (proxyRes.statusCode !== 200) {
@@ -34759,7 +34761,8 @@ async function startNeovimMode(opts) {
34759
34761
  return;
34760
34762
  }
34761
34763
  if (state.focused) {
34762
- nvimPty.write(seq);
34764
+ const normalized = seq.replace(/\x1BO([ABCD])/g, "\x1B[$1");
34765
+ nvimPty.write(normalized);
34763
34766
  }
34764
34767
  };
34765
34768
  stdin.on("data", state.stdinHandler);
@@ -34830,8 +34833,13 @@ async function connectRPC(state, neovimPkg, cols) {
34830
34833
  if (state.cleanedUp)
34831
34834
  return;
34832
34835
  try {
34833
- const editorWidth = Math.floor(cols * 0.7);
34834
- const outputWidth = cols - editorWidth;
34836
+ await new Promise((r) => setTimeout(r, 600));
34837
+ if (state.cleanedUp)
34838
+ return;
34839
+ const neoTreeWidth = 30;
34840
+ const remainingWidth = cols - neoTreeWidth;
34841
+ const outputWidth = Math.max(30, Math.floor(remainingWidth * 0.35));
34842
+ await nvim.command("wincmd l");
34835
34843
  await nvim.command("botright vsplit");
34836
34844
  await nvim.command(`vertical resize ${outputWidth}`);
34837
34845
  const buf = await nvim.createBuffer(false, true);
@@ -34992,7 +35000,7 @@ var init_neovim_mode = __esm({
34992
35000
  init_setup();
34993
35001
  isTTY5 = process.stdout.isTTY ?? false;
34994
35002
  PTY_MODE_ENABLE_RE = /\x1B\[\?(?:1000|1002|1003|1004|1005|1006|1015|2004)h/g;
34995
- STDIN_MOUSE_FOCUS_RE = /\x1B\[<[\d;]+[Mm]|\x1B\[M[\s\S]{3}|\x1B\[[IO]/g;
35003
+ STDIN_MOUSE_FOCUS_RE = /\x1B\[<[\d;]+[Mm]|\x1B\[M[\s\S]{3}|\x1B\[[IO]|\x1BO[ABCD]/g;
34996
35004
  _state = null;
34997
35005
  }
34998
35006
  });
@@ -37423,6 +37431,13 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
37423
37431
  });
37424
37432
 
37425
37433
  // packages/cli/dist/tui/commands.js
37434
+ function safeLog(text) {
37435
+ if (isNeovimActive()) {
37436
+ writeToNeovimOutput(text + "\n");
37437
+ } else {
37438
+ process.stdout.write(text + "\n");
37439
+ }
37440
+ }
37426
37441
  async function handleSlashCommand(input, ctx) {
37427
37442
  const trimmed = input.trim();
37428
37443
  if (!trimmed.startsWith("/"))
@@ -37489,7 +37504,7 @@ async function handleSlashCommand(input, ctx) {
37489
37504
  }
37490
37505
  }
37491
37506
  lines.push("");
37492
- console.log(lines.join("\n"));
37507
+ safeLog(lines.join("\n"));
37493
37508
  } else {
37494
37509
  renderInfo("Cost tracking not available.");
37495
37510
  }
@@ -37521,7 +37536,7 @@ async function handleSlashCommand(input, ctx) {
37521
37536
  lines.push(` ${c2.dim(evalResult.feedback)}`);
37522
37537
  }
37523
37538
  lines.push("");
37524
- console.log(lines.join("\n"));
37539
+ safeLog(lines.join("\n"));
37525
37540
  } else {
37526
37541
  renderError(`Evaluation failed: ${evalResult.error}`);
37527
37542
  }
@@ -37758,9 +37773,9 @@ async function handleSlashCommand(input, ctx) {
37758
37773
  const template = getTaskTemplate(type);
37759
37774
  ctx.setTaskType?.(type);
37760
37775
  renderInfo(`Task type: ${c2.bold(template.label)} (${type})`);
37761
- console.log(` ${c2.dim(template.description)}`);
37762
- console.log(` ${c2.dim("Recommended tools:")} ${template.recommendedTools.slice(0, 5).join(", ")}`);
37763
- console.log("");
37776
+ safeLog(` ${c2.dim(template.description)}`);
37777
+ safeLog(` ${c2.dim("Recommended tools:")} ${template.recommendedTools.slice(0, 5).join(", ")}`);
37778
+ safeLog("");
37764
37779
  } else {
37765
37780
  const lines = [];
37766
37781
  lines.push(`
@@ -37779,7 +37794,7 @@ async function handleSlashCommand(input, ctx) {
37779
37794
  lines.push(`
37780
37795
  ${c2.dim("Usage: /task-type <type> or /task-type auto")}`);
37781
37796
  lines.push("");
37782
- console.log(lines.join("\n"));
37797
+ safeLog(lines.join("\n"));
37783
37798
  }
37784
37799
  return "handled";
37785
37800
  }
@@ -37838,7 +37853,7 @@ async function handleSlashCommand(input, ctx) {
37838
37853
  Avg eval score: ${c2.bold(`${Math.round(summary.averageEvalScore * 100)}%`)}`);
37839
37854
  }
37840
37855
  lines.push("");
37841
- console.log(lines.join("\n"));
37856
+ safeLog(lines.join("\n"));
37842
37857
  return "handled";
37843
37858
  }
37844
37859
  case "model":
@@ -39702,19 +39717,19 @@ async function handleParallel(arg, ctx) {
39702
39717
  } catch {
39703
39718
  }
39704
39719
  const effective = envVal || systemdVal || "1 (default)";
39705
- console.log("");
39706
- console.log(` ${c2.bold("Parallel Inference Slots")}`);
39707
- console.log("");
39708
- console.log(` ${c2.dim("OLLAMA_NUM_PARALLEL:")} ${c2.bold(c2.cyan(effective))}`);
39709
- console.log(` ${c2.dim("Endpoint:")} ${baseUrl}`);
39720
+ safeLog("");
39721
+ safeLog(` ${c2.bold("Parallel Inference Slots")}`);
39722
+ safeLog("");
39723
+ safeLog(` ${c2.dim("OLLAMA_NUM_PARALLEL:")} ${c2.bold(c2.cyan(effective))}`);
39724
+ safeLog(` ${c2.dim("Endpoint:")} ${baseUrl}`);
39710
39725
  if (runningInfo) {
39711
- console.log(` ${c2.dim("Running models:")}`);
39712
- console.log(runningInfo);
39726
+ safeLog(` ${c2.dim("Running models:")}`);
39727
+ safeLog(runningInfo);
39713
39728
  }
39714
- console.log("");
39715
- console.log(` ${c2.dim("Set with:")} ${c2.cyan("/parallel <1-15>")}`);
39716
- console.log(` ${c2.dim("Each slot multiplies context memory usage per model.")}`);
39717
- console.log("");
39729
+ safeLog("");
39730
+ safeLog(` ${c2.dim("Set with:")} ${c2.cyan("/parallel <1-15>")}`);
39731
+ safeLog(` ${c2.dim("Each slot multiplies context memory usage per model.")}`);
39732
+ safeLog("");
39718
39733
  return;
39719
39734
  }
39720
39735
  const n = parseInt(arg, 10);
@@ -39842,23 +39857,34 @@ async function handleUpdate(subcommand, ctx) {
39842
39857
  } catch {
39843
39858
  }
39844
39859
  const BRAILLE_CYCLE = ["\u2800", "\u2840", "\u28C0", "\u28C4", "\u28E4", "\u28E6", "\u28F6", "\u28F7", "\u28FF", "\u28F7", "\u28F6", "\u28E6", "\u28E4", "\u28C4", "\u28C0", "\u2840"];
39860
+ const safeWrite = (text) => {
39861
+ if (isNeovimActive()) {
39862
+ writeToNeovimOutput(text);
39863
+ } else {
39864
+ process.stdout.write(text);
39865
+ }
39866
+ };
39845
39867
  function startInlineSpinner(prefix) {
39846
39868
  let frame = 0;
39869
+ const nvActive = isNeovimActive();
39847
39870
  const timer = setInterval(() => {
39871
+ if (nvActive)
39872
+ return;
39848
39873
  const braille = BRAILLE_CYCLE[frame % BRAILLE_CYCLE.length];
39849
39874
  process.stdout.write(`\r ${c2.cyan("\u25CF")} ${prefix} ${c2.cyan(braille)}`);
39850
39875
  frame++;
39851
39876
  }, 80);
39852
- process.stdout.write(` ${c2.cyan("\u25CF")} ${prefix} ${c2.cyan(BRAILLE_CYCLE[0])}`);
39877
+ safeWrite(` ${c2.cyan("\u25CF")} ${prefix} ${c2.cyan(BRAILLE_CYCLE[0])}
39878
+ `);
39853
39879
  return {
39854
39880
  stop(completionText) {
39855
39881
  clearInterval(timer);
39856
- process.stdout.write(`\r ${c2.green("\u2714")} ${completionText}${" ".repeat(20)}
39882
+ safeWrite(`\r ${c2.green("\u2714")} ${completionText}${" ".repeat(20)}
39857
39883
  `);
39858
39884
  }
39859
39885
  };
39860
39886
  }
39861
- process.stdout.write("\n");
39887
+ safeWrite("\n");
39862
39888
  const checkSpinner = startInlineSpinner(`Checking for updates ${c2.dim(`(current: v${currentVersion})`)}`);
39863
39889
  const info = await checkForUpdate(currentVersion, true);
39864
39890
  const { exec: exec4, execSync: es2 } = await import("node:child_process");
@@ -39885,7 +39911,7 @@ async function handleUpdate(subcommand, ctx) {
39885
39911
  if (needsSudo) {
39886
39912
  renderInfo("Global npm directory requires elevated permissions.");
39887
39913
  renderInfo("You'll be asked for your password once \u2014 it covers all update steps.");
39888
- process.stdout.write("\n");
39914
+ safeWrite("\n");
39889
39915
  try {
39890
39916
  es2("sudo -v", { stdio: "inherit", timeout: 6e4 });
39891
39917
  } catch {
@@ -39957,7 +39983,7 @@ async function handleUpdate(subcommand, ctx) {
39957
39983
  depsSpinner.stop(depsUpdated ? "Dependencies updated to latest." : "Dependencies checked.");
39958
39984
  if (!primaryUpdated && !depsUpdated) {
39959
39985
  renderInfo("Everything is up to date \u2014 no changes needed.");
39960
- process.stdout.write("\n");
39986
+ safeWrite("\n");
39961
39987
  return;
39962
39988
  }
39963
39989
  const rebuildSpinner = startInlineSpinner("Rebuilding native modules");
@@ -47791,7 +47817,7 @@ var init_status_bar = __esm({
47791
47817
  }
47792
47818
  /** Expose gateway status — shown after capability emojis */
47793
47819
  _expose = null;
47794
- /** Blink state for expose icon during active inference router LED pattern */
47820
+ /** Blink state for expose icon driven by token generation events */
47795
47821
  _exposeBlinkOn = true;
47796
47822
  _exposeBlinkTimer = null;
47797
47823
  /** Trail timer — keeps blinking briefly after connections drop */
@@ -47799,6 +47825,8 @@ var init_status_bar = __esm({
47799
47825
  /** Rolling request count for activity-based trail duration */
47800
47826
  _exposeRecentReqs = 0;
47801
47827
  _exposeLastReqCount = 0;
47828
+ /** Token-driven flash: OFF timeout after each token triggers ON */
47829
+ _exposeTokenFlashTimer = null;
47802
47830
  /** Update expose gateway status */
47803
47831
  setExposeStatus(status) {
47804
47832
  this._expose = status;
@@ -47847,11 +47875,36 @@ var init_status_bar = __esm({
47847
47875
  clearTimeout(this._exposeTrailTimer);
47848
47876
  this._exposeTrailTimer = null;
47849
47877
  }
47878
+ if (this._exposeTokenFlashTimer) {
47879
+ clearTimeout(this._exposeTokenFlashTimer);
47880
+ this._exposeTokenFlashTimer = null;
47881
+ }
47850
47882
  this._exposeBlinkOn = true;
47851
47883
  this._exposeRecentReqs = 0;
47852
47884
  if (this.active)
47853
47885
  this.renderFooterPreserveCursor();
47854
47886
  }
47887
+ /**
47888
+ * Flash the expose LED once per token — called during active inference when
47889
+ * this node is serving tokens to remote clients. Each call turns the LED ON
47890
+ * for ~50ms then back OFF, creating a 1:1 visual link between generated
47891
+ * tokens and the LED activity indicator (like a network TX LED on a router).
47892
+ */
47893
+ flashExposeToken() {
47894
+ if (!this._expose || this._expose.status !== "active")
47895
+ return;
47896
+ this._exposeBlinkOn = true;
47897
+ if (this._exposeTokenFlashTimer)
47898
+ clearTimeout(this._exposeTokenFlashTimer);
47899
+ this._exposeTokenFlashTimer = setTimeout(() => {
47900
+ this._exposeBlinkOn = false;
47901
+ this._exposeTokenFlashTimer = null;
47902
+ if (this.active)
47903
+ this.renderFooterPreserveCursor();
47904
+ }, 50);
47905
+ if (this.active)
47906
+ this.renderFooterPreserveCursor();
47907
+ }
47855
47908
  /** Unified system metrics collector (local or remote) */
47856
47909
  _metricsCollector = new SystemMetricsCollector();
47857
47910
  /** Cached unified metrics snapshot — updated by collector callback */
@@ -49271,14 +49324,18 @@ function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce
49271
49324
  const msg = `
49272
49325
  [cascade] Failover \u2192 ${to.label ?? to.url}: ${reason}
49273
49326
  `;
49274
- if (!bufferIfOverlay("stderr", msg))
49327
+ if (isNeovimActive()) {
49328
+ writeToNeovimOutput(msg);
49329
+ } else if (!bufferIfOverlay("stderr", msg))
49275
49330
  process.stderr.write(msg);
49276
49331
  },
49277
49332
  onProbeResult: (ep, success) => {
49278
49333
  if (success) {
49279
49334
  const msg = `[cascade] Primary recovered: ${ep.label ?? ep.url}
49280
49335
  `;
49281
- if (!bufferIfOverlay("stderr", msg))
49336
+ if (isNeovimActive()) {
49337
+ writeToNeovimOutput(msg);
49338
+ } else if (!bufferIfOverlay("stderr", msg))
49282
49339
  process.stderr.write(msg);
49283
49340
  }
49284
49341
  }
@@ -50326,7 +50383,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50326
50383
  const contentRows = statusBar.isActive ? statusBar.availableContentRows : Math.max(5, (process.stdout.rows ?? 24) - 6);
50327
50384
  resizeNeovim(process.stdout.columns ?? 80, contentRows);
50328
50385
  }
50329
- if (!carouselRetired) {
50386
+ if (!carouselRetired && !isNeovimActive()) {
50330
50387
  const termRows = process.stdout.rows ?? 24;
50331
50388
  const scrollStart = carousel.reservedRows + 1;
50332
50389
  const scrollEnd = Math.max(termRows - statusBar.reservedRows, scrollStart + 1);
@@ -50397,6 +50454,33 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50397
50454
  fn();
50398
50455
  }
50399
50456
  }
50457
+ async function writeContentAsync(fn) {
50458
+ if (isNeovimActive()) {
50459
+ const origWrite = process.stdout.write;
50460
+ let captured = "";
50461
+ process.stdout.write = ((chunk) => {
50462
+ captured += typeof chunk === "string" ? chunk : Buffer.isBuffer(chunk) ? chunk.toString() : "";
50463
+ return true;
50464
+ });
50465
+ try {
50466
+ const result = await fn();
50467
+ return result;
50468
+ } finally {
50469
+ process.stdout.write = origWrite;
50470
+ if (captured)
50471
+ writeToNeovimOutput(captured);
50472
+ }
50473
+ }
50474
+ if (statusBar.isActive) {
50475
+ statusBar.beginContentWrite();
50476
+ try {
50477
+ return await fn();
50478
+ } finally {
50479
+ statusBar.endContentWrite();
50480
+ }
50481
+ }
50482
+ return fn();
50483
+ }
50400
50484
  (async () => {
50401
50485
  if (!isResumed && !isFirstRun()) {
50402
50486
  try {
@@ -50474,6 +50558,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50474
50558
  modelUsage: stats.modelUsage
50475
50559
  });
50476
50560
  });
50561
+ reconnected.on("token_flash", () => statusBar.flashExposeToken());
50477
50562
  writeContent(() => {
50478
50563
  renderInfo(`Reconnected to existing expose tunnel: ${reconnected.tunnelUrl}`);
50479
50564
  });
@@ -50664,6 +50749,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50664
50749
  }
50665
50750
  },
50666
50751
  clearScreen() {
50752
+ if (isNeovimActive()) {
50753
+ writeToNeovimOutput("[screen cleared]\n");
50754
+ return;
50755
+ }
50667
50756
  process.stdout.write("\x1B[2J\x1B[H");
50668
50757
  renderCompactHeader(currentConfig.model);
50669
50758
  if (statusBar.isActive)
@@ -51351,6 +51440,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
51351
51440
  modelUsage: stats.modelUsage
51352
51441
  });
51353
51442
  });
51443
+ newTunnel.on("token_flash", () => statusBar.flashExposeToken());
51354
51444
  try {
51355
51445
  const url = await newTunnel.start();
51356
51446
  tunnelGateway = newTunnel;
@@ -51614,6 +51704,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
51614
51704
  } else {
51615
51705
  writeContent(() => renderInfo(`No ${OA_DIR}/ directory found.`));
51616
51706
  }
51707
+ if (isNeovimActive())
51708
+ stopNeovimMode();
51617
51709
  process.stdout.write("\x1Bc");
51618
51710
  },
51619
51711
  contextSave() {
@@ -51872,11 +51964,7 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
51872
51964
  return;
51873
51965
  }
51874
51966
  if (input.startsWith("/")) {
51875
- if (statusBar.isActive)
51876
- statusBar.beginContentWrite();
51877
- const cmdResult = await handleSlashCommand(input, commandCtx);
51878
- if (statusBar.isActive)
51879
- statusBar.endContentWrite();
51967
+ const cmdResult = await writeContentAsync(() => handleSlashCommand(input, commandCtx));
51880
51968
  if (cmdResult === "exit") {
51881
51969
  if (activeTask) {
51882
51970
  activeTask.runner.abort();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.104.18",
3
+ "version": "0.104.19",
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",