open-agents-ai 0.138.56 → 0.138.58

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 +103 -19
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -40238,8 +40238,16 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
40238
40238
  if (torchCheck === "cpu") {
40239
40239
  renderWarning("GPU detected but PyTorch is CPU-only. Reinstalling with CUDA support in background...");
40240
40240
  try {
40241
- await this.asyncShell(`${JSON.stringify(venvPy)} -m pip install --quiet --force-reinstall torch torchaudio --index-url https://download.pytorch.org/whl/cu124`, 6e5);
40242
- renderInfo("PyTorch reinstalled with CUDA GPU support.");
40241
+ const detectScript = join50(__dirname, "../../../../scripts/detect-torch.py");
40242
+ let pipArgs = `torch torchaudio --index-url https://download.pytorch.org/whl/cu124`;
40243
+ try {
40244
+ const args = await this.asyncShell(`python3 ${JSON.stringify(detectScript)} --pip-args`, 1e4);
40245
+ if (args.trim())
40246
+ pipArgs = args.trim();
40247
+ } catch {
40248
+ }
40249
+ await this.asyncShell(`${JSON.stringify(venvPy)} -m pip install --quiet --force-reinstall ${pipArgs}`, 6e5);
40250
+ renderInfo("PyTorch reinstalled with GPU support.");
40243
40251
  } catch {
40244
40252
  }
40245
40253
  }
@@ -40262,32 +40270,39 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
40262
40270
  throw new Error(`Failed to create venv: ${err instanceof Error ? err.message : String(err)}`);
40263
40271
  }
40264
40272
  }
40265
- let hasCuda = false;
40266
- try {
40267
- await this.asyncShell("nvidia-smi", 5e3);
40268
- hasCuda = true;
40269
- } catch {
40270
- }
40271
- if (hasCuda) {
40272
- renderInfo(" Installing PyTorch (CUDA GPU)...");
40273
+ {
40274
+ const detectScript = join50(__dirname, "../../../../scripts/detect-torch.py");
40275
+ let pipArgsStr = "torch torchaudio";
40276
+ let torchDesc = "unknown platform";
40273
40277
  try {
40274
- await this.asyncShell(`${JSON.stringify(venvPy)} -m pip install --quiet torch torchaudio --index-url https://download.pytorch.org/whl/cu124`, 6e5);
40278
+ const detectResult = await this.asyncShell(`${py} ${JSON.stringify(detectScript)} --json`, 15e3);
40279
+ const spec = JSON.parse(detectResult.trim());
40280
+ pipArgsStr = spec.pip_args_str || "torch torchaudio";
40281
+ torchDesc = spec.description || `${spec.platform} ${spec.arch} ${spec.accelerator}`;
40275
40282
  } catch {
40276
40283
  try {
40277
- await this.asyncShell(`${JSON.stringify(venvPy)} -m pip install --quiet torch torchaudio`, 6e5);
40278
- } catch (err2) {
40279
- throw new Error(`Failed to install PyTorch (CUDA): ${err2 instanceof Error ? err2.message : String(err2)}`);
40284
+ await this.asyncShell("nvidia-smi", 5e3);
40285
+ pipArgsStr = "torch torchaudio --index-url https://download.pytorch.org/whl/cu124";
40286
+ torchDesc = "CUDA (fallback)";
40287
+ } catch {
40288
+ const arch = process.arch;
40289
+ if (arch === "arm64" || arch === "arm") {
40290
+ pipArgsStr = "torch torchaudio";
40291
+ torchDesc = "ARM CPU (generic PyPI)";
40292
+ } else {
40293
+ pipArgsStr = "torch torchaudio --index-url https://download.pytorch.org/whl/cpu";
40294
+ torchDesc = "x86_64 CPU";
40295
+ }
40280
40296
  }
40281
40297
  }
40282
- } else {
40283
- renderInfo(" Installing PyTorch (CPU \u2014 no NVIDIA GPU detected)...");
40298
+ renderInfo(` Installing PyTorch (${torchDesc})...`);
40284
40299
  try {
40285
- await this.asyncShell(`${JSON.stringify(venvPy)} -m pip install --quiet torch torchaudio --index-url https://download.pytorch.org/whl/cpu`, 6e5);
40300
+ await this.asyncShell(`${JSON.stringify(venvPy)} -m pip install --quiet ${pipArgsStr}`, 6e5);
40286
40301
  } catch {
40287
40302
  try {
40288
40303
  await this.asyncShell(`${JSON.stringify(venvPy)} -m pip install --quiet torch torchaudio`, 6e5);
40289
40304
  } catch (err2) {
40290
- throw new Error(`Failed to install PyTorch: ${err2 instanceof Error ? err2.message : String(err2)}`);
40305
+ throw new Error(`Failed to install PyTorch (${torchDesc}): ${err2 instanceof Error ? err2.message : String(err2)}`);
40291
40306
  }
40292
40307
  }
40293
40308
  }
@@ -51597,6 +51612,11 @@ var init_status_bar = __esm({
51597
51612
  stdinHooked = false;
51598
51613
  /** COHERE distributed cognitive commons active flag */
51599
51614
  _cohereActive = false;
51615
+ /** Mouse tracking state — disabled when idle to allow native text selection */
51616
+ _mouseTrackingEnabled = true;
51617
+ _mouseIdleTimer = null;
51618
+ static MOUSE_IDLE_MS = 1500;
51619
+ // disable after 1.5s idle
51600
51620
  /** Banner refresh callback — called after resize to re-render top rows */
51601
51621
  _bannerRefresh = null;
51602
51622
  /** Track previous terminal dimensions to clear ghost separators on resize */
@@ -52199,6 +52219,47 @@ var init_status_bar = __esm({
52199
52219
  get cohereActive() {
52200
52220
  return this._cohereActive;
52201
52221
  }
52222
+ // ── Mouse tracking management ──────────────────────────────────────
52223
+ // Terminal mouse tracking (?1002h) captures all mouse events, preventing
52224
+ // native text selection. We disable it when idle (allowing selection) and
52225
+ // re-enable when scroll/streaming starts (allowing mouse scroll).
52226
+ // Users can always hold Shift for selection as a universal fallback.
52227
+ /** Enable mouse tracking (for scroll during streaming/scrollback) */
52228
+ enableMouseTracking() {
52229
+ if (this._mouseTrackingEnabled)
52230
+ return;
52231
+ this._mouseTrackingEnabled = true;
52232
+ if (process.stdout.isTTY) {
52233
+ this._trueStdoutWrite.call(process.stdout, "\x1B[?1002h\x1B[?1006h");
52234
+ }
52235
+ }
52236
+ /** Disable mouse tracking (allows native terminal text selection) */
52237
+ disableMouseTracking() {
52238
+ if (!this._mouseTrackingEnabled)
52239
+ return;
52240
+ this._mouseTrackingEnabled = false;
52241
+ if (process.stdout.isTTY) {
52242
+ this._trueStdoutWrite.call(process.stdout, "\x1B[?1002l\x1B[?1006l");
52243
+ }
52244
+ }
52245
+ /** Schedule mouse tracking disable after idle timeout.
52246
+ * Called after each content write or stream end. Cancelled by scroll/stream start. */
52247
+ scheduleMouseIdle() {
52248
+ if (this._mouseIdleTimer)
52249
+ clearTimeout(this._mouseIdleTimer);
52250
+ this._mouseIdleTimer = setTimeout(() => {
52251
+ if (!this.isStreaming && !this.isScrolledBack) {
52252
+ this.disableMouseTracking();
52253
+ }
52254
+ }, _StatusBar.MOUSE_IDLE_MS);
52255
+ }
52256
+ /** Cancel mouse idle timer (user is actively scrolling or streaming started) */
52257
+ cancelMouseIdle() {
52258
+ if (this._mouseIdleTimer) {
52259
+ clearTimeout(this._mouseIdleTimer);
52260
+ this._mouseIdleTimer = null;
52261
+ }
52262
+ }
52202
52263
  /** Set a callback to re-render the banner after resize/redraw */
52203
52264
  setBannerRefresh(refresh) {
52204
52265
  this._bannerRefresh = refresh;
@@ -52325,6 +52386,8 @@ var init_status_bar = __esm({
52325
52386
  return;
52326
52387
  this.writeDepth++;
52327
52388
  this._brailleSpinner.setMetrics({ isStreaming: true });
52389
+ this.cancelMouseIdle();
52390
+ this.enableMouseTracking();
52328
52391
  const rows = process.stdout.rows ?? 24;
52329
52392
  const scrollEnd = Math.max(rows - this._currentFooterHeight, this.scrollRegionTop + 1);
52330
52393
  if (this.writeDepth === 1 && !this._origWrite) {
@@ -52362,6 +52425,7 @@ ${CONTENT_BG_SEQ}`);
52362
52425
  process.stdout.write(RESET);
52363
52426
  this._brailleSpinner.setMetrics({ isStreaming: false });
52364
52427
  this.renderFooterAndPositionInput();
52428
+ this.scheduleMouseIdle();
52365
52429
  }
52366
52430
  }
52367
52431
  // -----------------------------------------------------------------------
@@ -52390,16 +52454,22 @@ ${CONTENT_BG_SEQ}`);
52390
52454
  scrollContentUp(lines = 1) {
52391
52455
  if (!this.active)
52392
52456
  return;
52457
+ this.cancelMouseIdle();
52458
+ this.enableMouseTracking();
52393
52459
  const maxOffset = Math.max(0, this._contentLines.length - this.contentHeight);
52394
52460
  this._contentScrollOffset = Math.min(maxOffset, this._contentScrollOffset + lines);
52395
52461
  this.repaintContent();
52462
+ this.scheduleMouseIdle();
52396
52463
  }
52397
52464
  /** Scroll down through content history */
52398
52465
  scrollContentDown(lines = 1) {
52399
52466
  if (!this.active)
52400
52467
  return;
52468
+ this.cancelMouseIdle();
52469
+ this.enableMouseTracking();
52401
52470
  this._contentScrollOffset = Math.max(0, this._contentScrollOffset - lines);
52402
52471
  this.repaintContent();
52472
+ this.scheduleMouseIdle();
52403
52473
  }
52404
52474
  /** Page up — scroll by visible height */
52405
52475
  pageUpContent() {
@@ -53208,10 +53278,12 @@ var init_mouse_filter = __esm({
53208
53278
  MouseFilterStream = class extends Transform {
53209
53279
  buffer = "";
53210
53280
  onScroll = null;
53281
+ onActivity = null;
53211
53282
  flushTimer = null;
53212
- constructor(scrollHandler) {
53283
+ constructor(scrollHandler, activityHandler) {
53213
53284
  super();
53214
53285
  this.onScroll = scrollHandler;
53286
+ this.onActivity = activityHandler ?? null;
53215
53287
  }
53216
53288
  _transform(chunk, _encoding, callback) {
53217
53289
  this.buffer += chunk.toString();
@@ -53231,6 +53303,8 @@ var init_mouse_filter = __esm({
53231
53303
  this.onScroll("up", 3, row);
53232
53304
  else if ((btn === 65 || btn === 97) && this.onScroll)
53233
53305
  this.onScroll("down", 3, row);
53306
+ if (this.onActivity)
53307
+ this.onActivity();
53234
53308
  i += mouseMatch[0].length;
53235
53309
  continue;
53236
53310
  }
@@ -54972,6 +55046,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
54972
55046
  else
54973
55047
  statusBar.scrollContentDown(lines);
54974
55048
  }
55049
+ }, () => {
55050
+ statusBar.cancelMouseIdle();
55051
+ statusBar.enableMouseTracking();
55052
+ statusBar.scheduleMouseIdle();
54975
55053
  });
54976
55054
  process.stdin.pipe(mouseFilter);
54977
55055
  const rl = readline2.createInterface({
@@ -55256,6 +55334,9 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
55256
55334
  return;
55257
55335
  }
55258
55336
  sudoPromptPending = true;
55337
+ if (process.stdout.isTTY) {
55338
+ process.stdout.write("\x1B[?1002l\x1B[?1006l");
55339
+ }
55259
55340
  writeContent(() => renderInfo("Password required for sudo. Type below, Enter to submit. Ctrl+O to show/hide."));
55260
55341
  const pwPrompt = `\x1B[38;5;178m\u{1F511}\x1B[0m `;
55261
55342
  rl.setPrompt(pwPrompt);
@@ -56627,6 +56708,9 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
56627
56708
  passwordShowPlain = false;
56628
56709
  sessionSudoPassword = input;
56629
56710
  activeTask.runner.setSudoPassword(input);
56711
+ if (process.stdout.isTTY) {
56712
+ process.stdout.write("\x1B[?1002h\x1B[?1006h");
56713
+ }
56630
56714
  statusBar.setInputStateProvider(() => ({
56631
56715
  line: rl.line ?? "",
56632
56716
  cursor: rl.cursor ?? 0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.138.56",
3
+ "version": "0.138.58",
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",