open-agents-ai 0.187.85 → 0.187.87

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 +152 -51
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -293376,6 +293376,17 @@ async function handleEndpoint(arg, ctx3, local = false) {
293376
293376
  detail: `${provider2} ${uses}${auth}`
293377
293377
  };
293378
293378
  });
293379
+ items.push({
293380
+ key: "__add__",
293381
+ label: `${c3.green("+")} Add endpoint`,
293382
+ detail: "Type a URL to add a new endpoint"
293383
+ });
293384
+ items.push({
293385
+ key: "__sponsor__",
293386
+ label: `${c3.cyan("\u2605")} Sponsored endpoints`,
293387
+ detail: "Discover free inference providers via Nexus"
293388
+ });
293389
+ let addedEndpoint = null;
293379
293390
  const result = await tuiSelect({
293380
293391
  items,
293381
293392
  activeKey: ctx3.config.backendUrl,
@@ -293383,10 +293394,41 @@ async function handleEndpoint(arg, ctx3, local = false) {
293383
293394
  rl: ctx3.rl,
293384
293395
  availableRows: ctx3.availableContentRows?.(),
293385
293396
  onDelete: (item, done) => {
293397
+ if (item.key.startsWith("__")) {
293398
+ done(false);
293399
+ return;
293400
+ }
293386
293401
  deleteUsageRecord("endpoint", item.key, ctx3.repoRoot);
293387
293402
  done(true);
293403
+ },
293404
+ onEnter: (item, { getInput, resolve: resolve39 }) => {
293405
+ if (item.key === "__add__") {
293406
+ getInput("URL", "http://").then(async (url2) => {
293407
+ if (!url2 || !url2.trim())
293408
+ return;
293409
+ const authKey = await getInput("Auth key (optional)", "");
293410
+ const trimmedUrl = url2.trim();
293411
+ const authArg = authKey?.trim() ? ` --auth ${authKey.trim()}` : "";
293412
+ addedEndpoint = `${trimmedUrl}${authArg}`;
293413
+ resolve39({ confirmed: true, key: "__add__", index: -1 });
293414
+ });
293415
+ return true;
293416
+ }
293417
+ if (item.key === "__sponsor__") {
293418
+ resolve39({ confirmed: true, key: "__sponsor__", index: -1 });
293419
+ return true;
293420
+ }
293421
+ return false;
293388
293422
  }
293389
293423
  });
293424
+ if (result.confirmed && result.key === "__add__" && addedEndpoint) {
293425
+ await handleEndpoint(addedEndpoint, ctx3, local);
293426
+ return;
293427
+ }
293428
+ if (result.confirmed && result.key === "__sponsor__") {
293429
+ await handleSponsoredEndpoint(ctx3, local);
293430
+ return;
293431
+ }
293390
293432
  if (result.confirmed && result.key) {
293391
293433
  const selectedRecord = history.find((h) => h.value === result.key);
293392
293434
  const savedAuth = selectedRecord?.meta?.authKey;
@@ -293398,34 +293440,55 @@ async function handleEndpoint(arg, ctx3, local = false) {
293398
293440
  return;
293399
293441
  }
293400
293442
  const currentProvider = detectProvider(ctx3.config.backendUrl);
293401
- process.stdout.write(`
293402
- ${c3.bold("Current endpoint:")}
293403
-
293404
- `);
293405
- process.stdout.write(` ${c3.cyan("Provider".padEnd(12))} ${currentProvider.label}
293406
- `);
293407
- process.stdout.write(` ${c3.cyan("URL".padEnd(12))} ${ctx3.config.backendUrl}
293408
- `);
293409
- process.stdout.write(` ${c3.cyan("Type".padEnd(12))} ${ctx3.config.backendType}
293410
- `);
293411
- process.stdout.write(` ${c3.cyan("Auth".padEnd(12))} ${ctx3.config.apiKey ? "Bearer token set" : "none"}
293412
- `);
293413
- process.stdout.write(`
293414
- ${c3.dim("Usage: /endpoint <url> [--auth <token>]")}
293415
- `);
293416
- process.stdout.write(` ${c3.dim(" /endpoint http://127.0.0.1:11434 Ollama")}
293417
- `);
293418
- process.stdout.write(` ${c3.dim(" /endpoint https://llm.chutes.ai --auth cpk_... Chutes AI")}
293419
- `);
293420
- process.stdout.write(` ${c3.dim(" /endpoint https://api.groq.com/openai --auth gsk_... Groq")}
293421
- `);
293422
- process.stdout.write(` ${c3.dim(" /endpoint https://api.together.xyz --auth ... Together AI")}
293423
- `);
293424
- process.stdout.write(` ${c3.dim(" /endpoint http://localhost:8000 vLLM")}
293425
- `);
293426
- process.stdout.write(` ${c3.dim(" /endpoint stop Reset to local Ollama")}
293427
-
293428
- `);
293443
+ const noHistItems = [
293444
+ {
293445
+ key: ctx3.config.backendUrl,
293446
+ label: `${currentProvider.label} \u2014 ${ctx3.config.backendUrl}`,
293447
+ detail: `${ctx3.config.backendType} ${ctx3.config.apiKey ? "Auth: Bearer token set" : "No auth"}`
293448
+ },
293449
+ {
293450
+ key: "__add__",
293451
+ label: `${c3.green("+")} Add endpoint`,
293452
+ detail: "Type a URL to add a new endpoint"
293453
+ },
293454
+ {
293455
+ key: "__sponsor__",
293456
+ label: `${c3.cyan("\u2605")} Sponsored endpoints`,
293457
+ detail: "Discover free inference providers via Nexus"
293458
+ }
293459
+ ];
293460
+ let addedUrl = null;
293461
+ const noHistResult = await tuiSelect({
293462
+ items: noHistItems,
293463
+ activeKey: ctx3.config.backendUrl,
293464
+ title: "Select Endpoint",
293465
+ rl: ctx3.rl,
293466
+ availableRows: ctx3.availableContentRows?.(),
293467
+ onEnter: (item, { getInput, resolve: resolve39 }) => {
293468
+ if (item.key === "__add__") {
293469
+ getInput("URL", "http://").then(async (url2) => {
293470
+ if (!url2?.trim())
293471
+ return;
293472
+ const authKey = await getInput("Auth key (optional)", "");
293473
+ addedUrl = `${url2.trim()}${authKey?.trim() ? ` --auth ${authKey.trim()}` : ""}`;
293474
+ resolve39({ confirmed: true, key: "__add__", index: -1 });
293475
+ });
293476
+ return true;
293477
+ }
293478
+ if (item.key === "__sponsor__") {
293479
+ resolve39({ confirmed: true, key: "__sponsor__", index: -1 });
293480
+ return true;
293481
+ }
293482
+ return false;
293483
+ }
293484
+ });
293485
+ if (noHistResult.confirmed && noHistResult.key === "__add__" && addedUrl) {
293486
+ await handleEndpoint(addedUrl, ctx3, local);
293487
+ } else if (noHistResult.confirmed && noHistResult.key === "__sponsor__") {
293488
+ await handleSponsoredEndpoint(ctx3, local);
293489
+ } else if (!noHistResult.confirmed) {
293490
+ renderInfo("Endpoint selection cancelled.");
293491
+ }
293429
293492
  return;
293430
293493
  }
293431
293494
  if (arg === "stop" || arg === "off" || arg.startsWith("stop ") || arg.startsWith("off ")) {
@@ -294277,18 +294340,21 @@ async function handleUpdate(subcommand, ctx3) {
294277
294340
  }
294278
294341
  };
294279
294342
  const PROGRESS_BLOCKS = [" ", "\u2801", "\u2803", "\u2807", "\u280F", "\u281F", "\u283F", "\u28FF"];
294343
+ const BRAILLE_SPINNER = ["\u2801", "\u2803", "\u2807", "\u280F", "\u281F", "\u283F", "\u28FF", "\u28FE", "\u28FC", "\u28F8", "\u28F0", "\u28E0", "\u28C0", "\u2880"];
294280
294344
  let _installProgress = 0;
294281
294345
  let _installTotal = 10;
294282
- function renderInstallFrame(version4, _frame, statusLine) {
294346
+ let _installPhase = "";
294347
+ function renderInstallFrame(version4, frame, statusLine) {
294283
294348
  const L = layout();
294284
294349
  const cols = L.cols;
294285
- const { tuiAccent: getAccent, tuiBgSeq: getBgSeq, tuiBoxFg: getBoxFg } = (init_theme(), __toCommonJS(theme_exports));
294350
+ const { tuiAccent: getAccent, tuiBgSeq: getBgSeq, tuiBoxFg: getBoxFg, tuiTextDim: getDimColor } = (init_theme(), __toCommonJS(theme_exports));
294286
294351
  const accentColor = getAccent() < 0 ? 252 : getAccent();
294287
294352
  const boxFg = getBoxFg();
294288
294353
  const bgSeq = getBgSeq();
294289
294354
  const contentTop = L.contentTop;
294290
294355
  const contentBottom = L.contentBottom;
294291
294356
  const contentHeight = L.contentHeight;
294357
+ const isDone = statusLine === "__DONE__";
294292
294358
  let buf = "\x1B[?2026h\x1B7\x1B[?25l";
294293
294359
  for (let r2 = contentTop; r2 <= contentBottom; r2++) {
294294
294360
  buf += `\x1B[${r2};1H${bgSeq}\x1B[2K`;
@@ -294305,32 +294371,42 @@ async function handleUpdate(subcommand, ctx3) {
294305
294371
  buf += `\x1B[${boxTop + r2};${boxLeft}H${boxFg}\u2502${bgSeq}${" ".repeat(innerW)}${boxFg}\u2502`;
294306
294372
  }
294307
294373
  buf += `\x1B[${boxTop + boxH - 1};${boxLeft}H${boxFg}\u2570${"\u2500".repeat(innerW)}\u256F`;
294308
- const isDone = statusLine === "__DONE__";
294309
294374
  const label = isDone ? "INSTALLED" : "INSTALLING";
294310
294375
  const labelColor = isDone ? 82 : accentColor;
294311
- const labelCol = centerCol - Math.floor(label.length / 2);
294312
- buf += `\x1B[${boxTop + 1};${labelCol}H\x1B[1;38;5;${labelColor}m${label}\x1B[0m`;
294376
+ const spinner = isDone ? " \u2713" : ` ${BRAILLE_SPINNER[frame % BRAILLE_SPINNER.length]}`;
294377
+ const fullLabel = label + spinner;
294378
+ const labelCol = centerCol - Math.floor(fullLabel.length / 2);
294379
+ buf += `\x1B[${boxTop + 1};${labelCol}H\x1B[1;38;5;${labelColor}m${label}\x1B[0m\x1B[38;5;${labelColor}m${spinner}\x1B[0m`;
294313
294380
  const progress = isDone ? 1 : Math.min(0.95, _installProgress / Math.max(1, _installTotal));
294314
294381
  const barW = innerW - 4;
294315
- const filledCols = Math.floor(progress * barW);
294316
- let bar = "";
294317
- for (let c4 = 0; c4 < barW; c4++) {
294318
- if (c4 < filledCols) {
294319
- bar += PROGRESS_BLOCKS[PROGRESS_BLOCKS.length - 1];
294320
- } else if (c4 === filledCols) {
294321
- const subProgress = progress * barW - filledCols;
294322
- const idx = Math.floor(subProgress * (PROGRESS_BLOCKS.length - 1));
294323
- bar += PROGRESS_BLOCKS[idx] ?? " ";
294324
- } else {
294325
- bar += PROGRESS_BLOCKS[0];
294382
+ const barCol = boxLeft + 3;
294383
+ if (_installProgress === 0 && !isDone) {
294384
+ let bar = "";
294385
+ for (let c4 = 0; c4 < barW; c4++) {
294386
+ const wave = Math.sin((c4 - frame * 0.8) * 0.3);
294387
+ const idx = Math.max(0, Math.min(PROGRESS_BLOCKS.length - 1, Math.floor((wave + 1) * 0.5 * (PROGRESS_BLOCKS.length - 1))));
294388
+ bar += PROGRESS_BLOCKS[idx];
294389
+ }
294390
+ buf += `\x1B[${boxTop + 2};${barCol}H\x1B[38;5;${accentColor}m${bar}\x1B[0m`;
294391
+ } else {
294392
+ const filledCols = Math.floor(progress * barW);
294393
+ let bar = "";
294394
+ for (let c4 = 0; c4 < barW; c4++) {
294395
+ if (c4 < filledCols) {
294396
+ bar += PROGRESS_BLOCKS[PROGRESS_BLOCKS.length - 1];
294397
+ } else if (c4 === filledCols) {
294398
+ const edgeIdx = isDone ? PROGRESS_BLOCKS.length - 1 : frame % (PROGRESS_BLOCKS.length - 1) + 1;
294399
+ bar += PROGRESS_BLOCKS[edgeIdx];
294400
+ } else {
294401
+ bar += PROGRESS_BLOCKS[0];
294402
+ }
294326
294403
  }
294404
+ buf += `\x1B[${boxTop + 2};${barCol}H\x1B[38;5;${accentColor}m${bar}\x1B[0m`;
294327
294405
  }
294328
- const barCol = boxLeft + 3;
294329
- buf += `\x1B[${boxTop + 2};${barCol}H\x1B[38;5;${accentColor}m${bar}\x1B[0m`;
294330
- const statusText = isDone ? `v${version4}` : statusLine || `v${version4}`;
294406
+ const phaseText = _installPhase ? `${_installPhase}` : "";
294407
+ const statusText = isDone ? `v${version4}` : statusLine || phaseText || `v${version4}`;
294331
294408
  const statusTrunc = statusText.slice(0, innerW - 2);
294332
294409
  const sCol = centerCol - Math.floor(statusTrunc.length / 2);
294333
- const { tuiTextDim: getDimColor } = (init_theme(), __toCommonJS(theme_exports));
294334
294410
  buf += `\x1B[${boxTop + 3};${sCol}H\x1B[38;5;${getDimColor()}m${statusTrunc}\x1B[0m`;
294335
294411
  buf += `\x1B[0m\x1B8\x1B[?25h\x1B[?2026l`;
294336
294412
  process.stdout.write(buf);
@@ -294343,22 +294419,29 @@ async function handleUpdate(subcommand, ctx3) {
294343
294419
  const timer = setInterval(() => {
294344
294420
  frame++;
294345
294421
  renderInstallFrame(version4, frame, status);
294346
- }, 200);
294422
+ }, 80);
294347
294423
  return {
294348
294424
  setStatus(text) {
294349
294425
  status = text;
294350
294426
  },
294427
+ setPhase(phase) {
294428
+ _installPhase = phase;
294429
+ },
294430
+ setProgress(current, total) {
294431
+ _installProgress = current;
294432
+ _installTotal = total;
294433
+ },
294351
294434
  stop(finalText) {
294352
294435
  clearInterval(timer);
294353
294436
  unlockFooterRedraws();
294354
294437
  status = "__DONE__";
294438
+ _installProgress = _installTotal;
294355
294439
  renderInstallFrame(version4, frame, status);
294356
294440
  setTimeout(() => {
294357
294441
  status = finalText;
294358
294442
  renderInstallFrame(version4, frame + 1, finalText);
294359
294443
  }, 300);
294360
294444
  },
294361
- /** Clear the overlay content area entirely — return to normal scroll area */
294362
294445
  dismiss() {
294363
294446
  unlockFooterRedraws();
294364
294447
  clearInterval(timer);
@@ -294553,7 +294636,8 @@ async function handleUpdate(subcommand, ctx3) {
294553
294636
  const installOverlay = startInstallOverlay(targetVersion);
294554
294637
  let installError = "";
294555
294638
  _installProgress = 0;
294556
- _installTotal = 10;
294639
+ _installTotal = 20;
294640
+ _installPhase = "Preparing...";
294557
294641
  const runInstall2 = (cmd) => new Promise((resolve39) => {
294558
294642
  const child = exec4(cmd, { timeout: 18e4 }, (err, _stdout, stderr) => {
294559
294643
  if (err)
@@ -294603,7 +294687,11 @@ async function handleUpdate(subcommand, ctx3) {
294603
294687
  const sudoPrefix = needsSudo ? "sudo " : "";
294604
294688
  let primaryUpdated = false;
294605
294689
  let depsUpdated = false;
294690
+ const totalPhases = (doPackage && info ? 5 : 0) + (doDeps ? 5 : 0) + (doRebuild ? 3 : 0) + (doPython ? 3 : 0) + (doCloudflared ? 2 : 0) + (doOllama ? 2 : 0);
294691
+ let completedPhases = 0;
294692
+ installOverlay.setProgress(0, totalPhases || 1);
294606
294693
  if (doPackage && info) {
294694
+ installOverlay.setPhase("Package");
294607
294695
  installOverlay.setStatus("Installing package...");
294608
294696
  const installCmd = `${sudoPrefix}npm install -g open-agents-ai@latest --prefer-online`;
294609
294697
  let installOk = await runInstall2(installCmd);
@@ -294640,10 +294728,13 @@ async function handleUpdate(subcommand, ctx3) {
294640
294728
  renderWarning(`Try manually: ${hint}`);
294641
294729
  return;
294642
294730
  }
294731
+ completedPhases += 5;
294732
+ installOverlay.setProgress(completedPhases, totalPhases);
294643
294733
  installOverlay.setStatus(`Package installed (v${info.latestVersion})`);
294644
294734
  primaryUpdated = true;
294645
294735
  }
294646
294736
  if (doDeps) {
294737
+ installOverlay.setPhase("Dependencies");
294647
294738
  installOverlay.setStatus("Checking sub-dependencies...");
294648
294739
  try {
294649
294740
  const prefix = await execA("npm prefix -g", { timeout: 5e3 });
@@ -294701,9 +294792,12 @@ async function handleUpdate(subcommand, ctx3) {
294701
294792
  }
294702
294793
  } catch {
294703
294794
  }
294795
+ completedPhases += 5;
294796
+ installOverlay.setProgress(completedPhases, totalPhases);
294704
294797
  installOverlay.setStatus(depsUpdated ? "Dependencies updated" : "Dependencies OK");
294705
294798
  }
294706
294799
  if (doOllama) {
294800
+ installOverlay.setPhase("Ollama");
294707
294801
  installOverlay.setStatus("Updating Ollama...");
294708
294802
  try {
294709
294803
  const { updateOllama: doOllamaUpgrade } = await Promise.resolve().then(() => (init_setup(), setup_exports));
@@ -294774,18 +294868,22 @@ async function handleUpdate(subcommand, ctx3) {
294774
294868
  }
294775
294869
  }
294776
294870
  if (doRebuild) {
294871
+ installOverlay.setPhase("Native Modules");
294777
294872
  installOverlay.setStatus("Rebuilding native modules...");
294778
294873
  await new Promise((resolve39) => {
294779
294874
  const child = exec4(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () => resolve39(true));
294780
294875
  child.stdout?.resume();
294781
294876
  child.stderr?.resume();
294782
294877
  });
294878
+ completedPhases += 3;
294879
+ installOverlay.setProgress(completedPhases, totalPhases);
294783
294880
  installOverlay.setStatus("Native modules rebuilt");
294784
294881
  }
294785
294882
  const { existsSync: fsExists } = await import("node:fs");
294786
294883
  const { join: pathJoin } = await import("node:path");
294787
294884
  const { homedir: getHome } = await import("node:os");
294788
294885
  if (doPython) {
294886
+ installOverlay.setPhase("Python");
294789
294887
  let hasPython = hasCmd("python3") || hasCmd("python");
294790
294888
  if (!hasPython) {
294791
294889
  installOverlay.setStatus("Installing Python3...");
@@ -294821,9 +294919,12 @@ async function handleUpdate(subcommand, ctx3) {
294821
294919
  });
294822
294920
  installOverlay.setStatus("Python deps bootstrapped");
294823
294921
  }
294922
+ completedPhases += 3;
294923
+ installOverlay.setProgress(completedPhases, totalPhases);
294824
294924
  }
294825
294925
  let hasCf = false;
294826
294926
  if (doCloudflared) {
294927
+ installOverlay.setPhase("Cloudflared");
294827
294928
  installOverlay.setStatus("Checking cloudflared...");
294828
294929
  try {
294829
294930
  const { execSync: es } = await import("node:child_process");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.85",
3
+ "version": "0.187.87",
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",