open-agents-ai 0.68.1 → 0.68.3

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 +145 -7
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -24619,8 +24619,57 @@ function askSecret(rl, question) {
24619
24619
  stdin.on("data", onData);
24620
24620
  });
24621
24621
  }
24622
+ function ensureCurl() {
24623
+ if (hasCmd("curl"))
24624
+ return true;
24625
+ const plat = platform();
24626
+ if (plat === "win32") {
24627
+ process.stdout.write(` ${c2.yellow("\u26A0")} curl not found on Windows \u2014 install it manually.
24628
+ `);
24629
+ return false;
24630
+ }
24631
+ process.stdout.write(` ${c2.cyan("\u25CF")} curl not found. Installing...
24632
+ `);
24633
+ const strategies = [
24634
+ { check: "apt-get", install: "sudo apt-get update -qq && sudo apt-get install -y -qq curl", label: "apt" },
24635
+ { check: "dnf", install: "sudo dnf install -y -q curl", label: "dnf" },
24636
+ { check: "yum", install: "sudo yum install -y -q curl", label: "yum" },
24637
+ { check: "pacman", install: "sudo pacman -S --noconfirm curl", label: "pacman" },
24638
+ { check: "apk", install: "sudo apk add --quiet curl", label: "apk" },
24639
+ { check: "zypper", install: "sudo zypper install -y curl", label: "zypper" }
24640
+ ];
24641
+ for (const s of strategies) {
24642
+ if (hasCmd(s.check)) {
24643
+ try {
24644
+ execSync20(s.install, { stdio: "inherit", timeout: 12e4 });
24645
+ if (hasCmd("curl")) {
24646
+ process.stdout.write(` ${c2.green("\u2714")} curl installed via ${s.label}.
24647
+ `);
24648
+ return true;
24649
+ }
24650
+ } catch {
24651
+ process.stdout.write(` ${c2.yellow("\u26A0")} ${s.label} install failed, trying next...
24652
+ `);
24653
+ }
24654
+ }
24655
+ }
24656
+ if (plat === "darwin") {
24657
+ try {
24658
+ execSync20("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
24659
+ if (hasCmd("curl"))
24660
+ return true;
24661
+ } catch {
24662
+ }
24663
+ }
24664
+ process.stdout.write(` ${c2.red("\u2716")} Could not install curl. Install it manually and retry.
24665
+ `);
24666
+ return false;
24667
+ }
24622
24668
  async function autoInstallOllama(rl) {
24623
24669
  const plat = platform();
24670
+ if (plat !== "win32" && !ensureCurl()) {
24671
+ return false;
24672
+ }
24624
24673
  if (plat === "linux") {
24625
24674
  return installOllamaLinux();
24626
24675
  } else if (plat === "darwin") {
@@ -24750,6 +24799,64 @@ function installOllamaWindows() {
24750
24799
  return false;
24751
24800
  }
24752
24801
  }
24802
+ async function ensureOllamaRunning(backendUrl, rl) {
24803
+ const ollamaInstalled = hasCmd("ollama");
24804
+ if (!ollamaInstalled) {
24805
+ if (rl) {
24806
+ process.stdout.write(`
24807
+ ${c2.yellow("\u26A0")} Ollama is not installed on this system.
24808
+ `);
24809
+ const answer = await ask(rl, ` ${c2.bold("Install Ollama now?")} (Y/n) `);
24810
+ if (answer.toLowerCase() === "n") {
24811
+ return false;
24812
+ }
24813
+ } else {
24814
+ process.stdout.write(`
24815
+ ${c2.cyan("\u25CF")} Ollama not found. Installing automatically...
24816
+ `);
24817
+ }
24818
+ const installRl = rl ?? readline.createInterface({ input: process.stdin, output: process.stdout });
24819
+ const installed = await autoInstallOllama(installRl);
24820
+ if (!rl)
24821
+ installRl.close();
24822
+ if (!installed) {
24823
+ process.stdout.write(` ${c2.red("\u2716")} Ollama installation failed.
24824
+
24825
+ `);
24826
+ return false;
24827
+ }
24828
+ }
24829
+ process.stdout.write(` ${c2.cyan("\u25CF")} Starting ollama serve...
24830
+ `);
24831
+ try {
24832
+ const child = spawn12("ollama", ["serve"], { stdio: "ignore", detached: true });
24833
+ child.unref();
24834
+ } catch {
24835
+ process.stdout.write(` ${c2.yellow("\u26A0")} Could not start ollama serve.
24836
+
24837
+ `);
24838
+ return false;
24839
+ }
24840
+ for (let i = 0; i < 5; i++) {
24841
+ await new Promise((resolve28) => setTimeout(resolve28, 2e3));
24842
+ try {
24843
+ const resp = await fetch(`${backendUrl}/api/tags`, {
24844
+ signal: AbortSignal.timeout(3e3)
24845
+ });
24846
+ if (resp.ok) {
24847
+ process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
24848
+
24849
+ `);
24850
+ return true;
24851
+ }
24852
+ } catch {
24853
+ }
24854
+ }
24855
+ process.stdout.write(` ${c2.yellow("\u26A0")} Ollama started but not responding. Try ${c2.bold("ollama serve")} manually.
24856
+
24857
+ `);
24858
+ return false;
24859
+ }
24753
24860
  function pullModelWithAutoUpdate(tag) {
24754
24861
  try {
24755
24862
  execSync20(`ollama pull ${tag}`, {
@@ -24765,6 +24872,9 @@ function pullModelWithAutoUpdate(tag) {
24765
24872
  process.stdout.write(`
24766
24873
  ${c2.yellow("\u26A0")} Ollama needs to be updated for this model.
24767
24874
  `);
24875
+ if (!ensureCurl()) {
24876
+ throw new Error("curl is required to update Ollama but could not be installed.");
24877
+ }
24768
24878
  process.stdout.write(` ${c2.cyan("\u25CF")} Updating Ollama via official install script...
24769
24879
 
24770
24880
  `);
@@ -25524,6 +25634,10 @@ function ensureCloudflaredBackground(onInfo) {
25524
25634
  _cloudflaredInstallPromise = (async () => {
25525
25635
  const arch = process.arch;
25526
25636
  const os = platform();
25637
+ if (os !== "win32" && !ensureCurl()) {
25638
+ log("curl not available \u2014 cannot install cloudflared.");
25639
+ return false;
25640
+ }
25527
25641
  if (os === "linux") {
25528
25642
  const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
25529
25643
  const cfArch = archMap[arch] ?? "amd64";
@@ -26678,11 +26792,30 @@ async function handleEndpoint(arg, ctx, local = false) {
26678
26792
  } catch (err) {
26679
26793
  process.stdout.write(`${c2.yellow("\u26A0")} Could not verify
26680
26794
  `);
26681
- renderWarning(`Endpoint may not be reachable: ${err instanceof Error ? err.message : String(err)}`);
26682
- if (provider.authRequired && !apiKey) {
26683
- renderInfo(`${provider.label} typically requires an API key. Use: /endpoint ${url} --auth <key>`);
26795
+ if (provider.id === "ollama" && ctx.rl) {
26796
+ const running = await ensureOllamaRunning(normalizedUrl, ctx.rl);
26797
+ if (running) {
26798
+ try {
26799
+ const retryResp = await fetch(`${normalizedUrl}${provider.modelsPath}`, {
26800
+ signal: AbortSignal.timeout(5e3)
26801
+ });
26802
+ if (retryResp.ok) {
26803
+ process.stdout.write(` ${c2.green("\u2714")} Connected to Ollama.
26804
+ `);
26805
+ }
26806
+ } catch {
26807
+ }
26808
+ } else {
26809
+ renderWarning(`Endpoint may not be reachable: ${err instanceof Error ? err.message : String(err)}`);
26810
+ renderInfo("Setting endpoint anyway \u2014 it may come online later.");
26811
+ }
26812
+ } else {
26813
+ renderWarning(`Endpoint may not be reachable: ${err instanceof Error ? err.message : String(err)}`);
26814
+ if (provider.authRequired && !apiKey) {
26815
+ renderInfo(`${provider.label} typically requires an API key. Use: /endpoint ${url} --auth <key>`);
26816
+ }
26817
+ renderInfo("Setting endpoint anyway \u2014 it may come online later.");
26684
26818
  }
26685
- renderInfo("Setting endpoint anyway \u2014 it may come online later.");
26686
26819
  }
26687
26820
  ctx.setEndpoint(normalizedUrl, backendType, apiKey);
26688
26821
  const endpointSettings = { backendUrl: normalizedUrl, backendType, ...apiKey ? { apiKey } : {} };
@@ -36616,7 +36749,7 @@ async function startInteractive(config, repoPath) {
36616
36749
  const provider2 = detectProvider(config.backendUrl);
36617
36750
  renderWarning(`Cannot reach ${provider2.label} at ${config.backendUrl}`);
36618
36751
  if (provider2.id === "ollama") {
36619
- renderInfo("Start Ollama with: ollama serve");
36752
+ renderInfo("Use /endpoint http://127.0.0.1:11434 to auto-install & start Ollama.");
36620
36753
  }
36621
36754
  renderInfo("Use /endpoint to configure a different backend. Starting anyway...");
36622
36755
  }
@@ -37004,6 +37137,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
37004
37137
  get config() {
37005
37138
  return currentConfig;
37006
37139
  },
37140
+ rl,
37007
37141
  repoRoot,
37008
37142
  costTracker,
37009
37143
  workEvaluator,
@@ -38434,9 +38568,13 @@ async function runWithTUI(task, config, repoPath) {
38434
38568
  const provider2 = detectProvider(config.backendUrl);
38435
38569
  renderWarning(`Cannot reach ${provider2.label} at ${config.backendUrl}`);
38436
38570
  if (provider2.id === "ollama") {
38437
- renderInfo("Start Ollama with: ollama serve");
38571
+ const running = await ensureOllamaRunning(config.backendUrl);
38572
+ if (!running) {
38573
+ renderInfo("The agent will retry when you submit a task. Use /endpoint to reconfigure.");
38574
+ }
38575
+ } else {
38576
+ renderInfo("The agent will retry when you submit a task. Use /endpoint to reconfigure.");
38438
38577
  }
38439
- renderInfo("The agent will retry when you submit a task. Use /endpoint to reconfigure.");
38440
38578
  }
38441
38579
  renderCompactHeader(config.model);
38442
38580
  renderUserMessage(task);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.68.1",
3
+ "version": "0.68.3",
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",