open-agents-ai 0.30.4 → 0.30.5

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.
package/dist/index.js CHANGED
@@ -105,7 +105,7 @@ var init_config = __esm({
105
105
  "packages/cli/dist/config.js"() {
106
106
  "use strict";
107
107
  DEFAULT_CONFIG = Object.freeze({
108
- backendUrl: "http://localhost:11434",
108
+ backendUrl: "http://127.0.0.1:11434",
109
109
  model: "qwen3.5:latest",
110
110
  backendType: "ollama",
111
111
  apiKey: "",
@@ -6757,7 +6757,7 @@ Coordinates are normalized (0-1). Multiply by image width/height for pixel value
6757
6757
  }
6758
6758
  }
6759
6759
  async tryOllamaVision(buffer, filename, action, prompt, length, start) {
6760
- const ollamaHost = process.env["OLLAMA_HOST"] || "http://localhost:11434";
6760
+ const ollamaHost = process.env["OLLAMA_HOST"] || "http://127.0.0.1:11434";
6761
6761
  const envModel = process.env["OLLAMA_VISION_MODEL"];
6762
6762
  const model = envModel || (this._activeModelHasVision && this._activeModel ? this._activeModel : "moondream");
6763
6763
  const imageBase64 = buffer.toString("base64");
@@ -7079,7 +7079,7 @@ var init_desktop_click = __esm({
7079
7079
  }
7080
7080
  if (!visionWorked) {
7081
7081
  try {
7082
- const ollamaHost = process.env["OLLAMA_HOST"] || "http://localhost:11434";
7082
+ const ollamaHost = process.env["OLLAMA_HOST"] || "http://127.0.0.1:11434";
7083
7083
  const envModel = process.env["OLLAMA_VISION_MODEL"];
7084
7084
  const ollamaModel = envModel || (this._activeModelHasVision && this._activeModel ? this._activeModel : "moondream");
7085
7085
  const imageBase64 = readFileSync11(screenshotPath).toString("base64");
@@ -7253,7 +7253,7 @@ ${caption}`);
7253
7253
  }
7254
7254
  if (!visionWorked) {
7255
7255
  try {
7256
- const ollamaHost = process.env["OLLAMA_HOST"] || "http://localhost:11434";
7256
+ const ollamaHost = process.env["OLLAMA_HOST"] || "http://127.0.0.1:11434";
7257
7257
  const envModel = process.env["OLLAMA_VISION_MODEL"];
7258
7258
  const ollamaModel = envModel || (this._activeModelHasVision && this._activeModel ? this._activeModel : "moondream");
7259
7259
  const imageBase64 = imageBuffer.toString("base64");
@@ -12123,8 +12123,8 @@ function isTranscribablePath(path) {
12123
12123
  return isAudioPath(path) || isVideoPath(path);
12124
12124
  }
12125
12125
  function findMicCaptureCommand() {
12126
- const platform3 = process.platform;
12127
- if (platform3 === "linux") {
12126
+ const platform4 = process.platform;
12127
+ if (platform4 === "linux") {
12128
12128
  try {
12129
12129
  execSync12("which arecord", { stdio: "pipe" });
12130
12130
  return {
@@ -12134,7 +12134,7 @@ function findMicCaptureCommand() {
12134
12134
  } catch {
12135
12135
  }
12136
12136
  }
12137
- if (platform3 === "darwin") {
12137
+ if (platform4 === "darwin") {
12138
12138
  try {
12139
12139
  execSync12("which sox", { stdio: "pipe" });
12140
12140
  return {
@@ -12146,7 +12146,7 @@ function findMicCaptureCommand() {
12146
12146
  }
12147
12147
  try {
12148
12148
  execSync12("which ffmpeg", { stdio: "pipe" });
12149
- if (platform3 === "linux") {
12149
+ if (platform4 === "linux") {
12150
12150
  return {
12151
12151
  cmd: "ffmpeg",
12152
12152
  args: [
@@ -12165,7 +12165,7 @@ function findMicCaptureCommand() {
12165
12165
  "pipe:1"
12166
12166
  ]
12167
12167
  };
12168
- } else if (platform3 === "darwin") {
12168
+ } else if (platform4 === "darwin") {
12169
12169
  return {
12170
12170
  cmd: "ffmpeg",
12171
12171
  args: [
@@ -14334,10 +14334,10 @@ var init_oa_directory = __esm({
14334
14334
 
14335
14335
  // packages/cli/dist/tui/setup.js
14336
14336
  import * as readline from "node:readline";
14337
- import { execSync as execSync13 } from "node:child_process";
14337
+ import { execSync as execSync13, spawn as spawn8 } from "node:child_process";
14338
14338
  import { existsSync as existsSync15, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7 } from "node:fs";
14339
14339
  import { join as join22 } from "node:path";
14340
- import { homedir as homedir8 } from "node:os";
14340
+ import { homedir as homedir8, platform } from "node:os";
14341
14341
  function detectSystemSpecs() {
14342
14342
  let totalRamGB = 0;
14343
14343
  let availableRamGB = 0;
@@ -14424,6 +14424,148 @@ function ask(rl, question) {
14424
14424
  rl.question(question, (answer) => resolve19(answer.trim()));
14425
14425
  });
14426
14426
  }
14427
+ async function autoInstallOllama(rl) {
14428
+ const plat = platform();
14429
+ if (plat === "linux") {
14430
+ return installOllamaLinux();
14431
+ } else if (plat === "darwin") {
14432
+ return await installOllamaMac(rl);
14433
+ } else if (plat === "win32") {
14434
+ return installOllamaWindows();
14435
+ }
14436
+ process.stdout.write(` ${c2.yellow("\u26A0")} Unsupported platform: ${plat}
14437
+ `);
14438
+ process.stdout.write(` ${c2.dim("Visit https://ollama.com to install manually.")}
14439
+
14440
+ `);
14441
+ return false;
14442
+ }
14443
+ function installOllamaLinux() {
14444
+ process.stdout.write(`
14445
+ ${c2.cyan("\u25CF")} Installing Ollama via official install script...
14446
+
14447
+ `);
14448
+ try {
14449
+ execSync13("curl -fsSL https://ollama.com/install.sh | sh", {
14450
+ stdio: "inherit",
14451
+ timeout: 3e5
14452
+ });
14453
+ if (hasCmd("ollama")) {
14454
+ process.stdout.write(`
14455
+ ${c2.green("\u2714")} Ollama installed successfully.
14456
+ `);
14457
+ return true;
14458
+ }
14459
+ process.stdout.write(`
14460
+ ${c2.yellow("\u26A0")} Install script ran but ollama not found on PATH.
14461
+ `);
14462
+ return false;
14463
+ } catch (err) {
14464
+ process.stdout.write(`
14465
+ ${c2.red("\u2716")} Ollama install failed: ${err instanceof Error ? err.message : String(err)}
14466
+ `);
14467
+ return false;
14468
+ }
14469
+ }
14470
+ async function installOllamaMac(rl) {
14471
+ if (!hasCmd("brew")) {
14472
+ process.stdout.write(`
14473
+ ${c2.yellow("\u26A0")} Homebrew is not installed (needed for Ollama on macOS).
14474
+
14475
+ `);
14476
+ const installBrew = await ask(rl, ` ${c2.bold("Install Homebrew?")} (Y/n) `);
14477
+ if (installBrew.toLowerCase() === "n") {
14478
+ process.stdout.write(` ${c2.dim("Skipping Homebrew install.")}
14479
+
14480
+ `);
14481
+ return false;
14482
+ }
14483
+ process.stdout.write(`
14484
+ ${c2.cyan("\u25CF")} Installing Homebrew...
14485
+
14486
+ `);
14487
+ try {
14488
+ execSync13('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
14489
+ if (!hasCmd("brew")) {
14490
+ try {
14491
+ const brewPrefix = existsSync15("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
14492
+ process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
14493
+ } catch {
14494
+ }
14495
+ }
14496
+ if (hasCmd("brew")) {
14497
+ process.stdout.write(`
14498
+ ${c2.green("\u2714")} Homebrew installed.
14499
+ `);
14500
+ } else {
14501
+ process.stdout.write(`
14502
+ ${c2.yellow("\u26A0")} Homebrew install completed but brew not found on PATH.
14503
+ `);
14504
+ process.stdout.write(` ${c2.dim('Try: eval "$(/opt/homebrew/bin/brew shellenv)"')}
14505
+
14506
+ `);
14507
+ return false;
14508
+ }
14509
+ } catch (err) {
14510
+ process.stdout.write(`
14511
+ ${c2.red("\u2716")} Homebrew install failed: ${err instanceof Error ? err.message : String(err)}
14512
+ `);
14513
+ return false;
14514
+ }
14515
+ }
14516
+ process.stdout.write(`
14517
+ ${c2.cyan("\u25CF")} Installing Ollama via Homebrew...
14518
+
14519
+ `);
14520
+ try {
14521
+ execSync13("brew install ollama", {
14522
+ stdio: "inherit",
14523
+ timeout: 3e5
14524
+ });
14525
+ if (hasCmd("ollama")) {
14526
+ process.stdout.write(`
14527
+ ${c2.green("\u2714")} Ollama installed successfully.
14528
+ `);
14529
+ return true;
14530
+ }
14531
+ process.stdout.write(`
14532
+ ${c2.yellow("\u26A0")} brew install completed but ollama not found on PATH.
14533
+ `);
14534
+ return false;
14535
+ } catch (err) {
14536
+ process.stdout.write(`
14537
+ ${c2.red("\u2716")} Ollama install failed: ${err instanceof Error ? err.message : String(err)}
14538
+ `);
14539
+ return false;
14540
+ }
14541
+ }
14542
+ function installOllamaWindows() {
14543
+ process.stdout.write(`
14544
+ ${c2.cyan("\u25CF")} Installing Ollama via PowerShell...
14545
+
14546
+ `);
14547
+ try {
14548
+ execSync13('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
14549
+ stdio: "inherit",
14550
+ timeout: 3e5
14551
+ });
14552
+ if (hasCmd("ollama")) {
14553
+ process.stdout.write(`
14554
+ ${c2.green("\u2714")} Ollama installed successfully.
14555
+ `);
14556
+ return true;
14557
+ }
14558
+ process.stdout.write(`
14559
+ ${c2.yellow("\u26A0")} Install script ran but ollama not found on PATH.
14560
+ `);
14561
+ return false;
14562
+ } catch (err) {
14563
+ process.stdout.write(`
14564
+ ${c2.red("\u2716")} Ollama install failed: ${err instanceof Error ? err.message : String(err)}
14565
+ `);
14566
+ return false;
14567
+ }
14568
+ }
14427
14569
  function pullModelWithAutoUpdate(tag) {
14428
14570
  try {
14429
14571
  execSync13(`ollama pull ${tag}`, {
@@ -14624,32 +14766,81 @@ async function doSetup(config, rl) {
14624
14766
  process.stdout.write(` ${c2.yellow("\u26A0")} Cannot reach Ollama at ${c2.bold(config.backendUrl)}
14625
14767
 
14626
14768
  `);
14627
- const useWithout = await ask(rl, ` ${c2.bold("Use without Ollama?")} (y/n) `);
14628
- if (useWithout.toLowerCase() === "y" || useWithout.toLowerCase() === "yes") {
14629
- const endpointResult = await promptForCustomEndpoint(config, rl);
14630
- if (endpointResult) {
14631
- return endpointResult;
14769
+ const ollamaInstalled = hasCmd("ollama");
14770
+ if (ollamaInstalled) {
14771
+ process.stdout.write(` ${c2.cyan("\u25CF")} Ollama is installed but not running.
14772
+
14773
+ `);
14774
+ const startOllama = await ask(rl, ` ${c2.bold("Start Ollama now?")} (Y/n) `);
14775
+ if (startOllama.toLowerCase() !== "n") {
14776
+ process.stdout.write(`
14777
+ ${c2.cyan("\u25CF")} Starting ollama serve in background...
14778
+ `);
14779
+ try {
14780
+ const child = spawn8("ollama", ["serve"], { stdio: "ignore", detached: true });
14781
+ child.unref();
14782
+ await new Promise((resolve19) => setTimeout(resolve19, 3e3));
14783
+ try {
14784
+ models = await fetchOllamaModels(config.backendUrl);
14785
+ process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
14786
+
14787
+ `);
14788
+ } catch {
14789
+ process.stdout.write(` ${c2.yellow("\u26A0")} Ollama started but not responding yet. It may need a moment.
14790
+
14791
+ `);
14792
+ }
14793
+ } catch {
14794
+ process.stdout.write(` ${c2.yellow("\u26A0")} Could not start Ollama. Try running ${c2.bold("ollama serve")} manually.
14795
+
14796
+ `);
14797
+ }
14632
14798
  }
14633
- usingCustomEndpoint = true;
14634
14799
  } else {
14635
- process.stdout.write(`
14636
- ${c2.cyan("\u25CF")} Install Ollama: ${c2.bold(c2.cyan("https://ollama.com"))}
14800
+ const installOllama = await ask(rl, ` ${c2.bold("Install Ollama?")} (Y/n) `);
14801
+ if (installOllama.toLowerCase() !== "n") {
14802
+ const installed = await autoInstallOllama(rl);
14803
+ if (installed) {
14804
+ process.stdout.write(`
14805
+ ${c2.cyan("\u25CF")} Starting ollama serve...
14637
14806
  `);
14638
- process.stdout.write(` ${c2.dim("Linux:")} curl -fsSL https://ollama.com/install.sh | sh
14807
+ try {
14808
+ const child = spawn8("ollama", ["serve"], { stdio: "ignore", detached: true });
14809
+ child.unref();
14810
+ await new Promise((resolve19) => setTimeout(resolve19, 3e3));
14811
+ try {
14812
+ models = await fetchOllamaModels(config.backendUrl);
14813
+ process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
14814
+
14639
14815
  `);
14640
- process.stdout.write(` ${c2.dim("macOS:")} brew install ollama
14816
+ } catch {
14817
+ process.stdout.write(` ${c2.yellow("\u26A0")} Ollama installed but not responding yet. Try ${c2.bold("ollama serve")} manually.
14818
+
14641
14819
  `);
14642
- process.stdout.write(` ${c2.dim("Then:")} ollama serve
14820
+ }
14821
+ } catch {
14822
+ process.stdout.write(` ${c2.yellow("\u26A0")} Ollama installed. Start it with: ${c2.bold("ollama serve")}
14643
14823
 
14644
14824
  `);
14645
- const startAnyway = await ask(rl, ` ${c2.bold("Start anyway?")} (y/n) `);
14646
- if (startAnyway.toLowerCase() !== "y" && startAnyway.toLowerCase() !== "yes") {
14647
- process.stdout.write(`
14648
- ${c2.dim("You can always configure an endpoint later with /endpoint")}
14825
+ }
14826
+ }
14827
+ }
14828
+ if (models.length === 0) {
14829
+ const useCustom = await ask(rl, ` ${c2.bold("Use a custom inference endpoint instead?")} (y/n) `);
14830
+ if (useCustom.toLowerCase() === "y" || useCustom.toLowerCase() === "yes") {
14831
+ const endpointResult = await promptForCustomEndpoint(config, rl);
14832
+ if (endpointResult) {
14833
+ return endpointResult;
14834
+ }
14835
+ usingCustomEndpoint = true;
14836
+ } else {
14837
+ process.stdout.write(`
14838
+ ${c2.dim("You can configure an endpoint later with /endpoint")}
14649
14839
 
14650
14840
  `);
14841
+ return config.model;
14842
+ }
14651
14843
  }
14652
- return config.model;
14653
14844
  }
14654
14845
  }
14655
14846
  if (usingCustomEndpoint) {
@@ -15657,7 +15848,7 @@ async function handleEndpoint(arg, ctx, local = false) {
15657
15848
  process.stdout.write(`
15658
15849
  ${c2.dim("Usage: /endpoint <url> [--auth <token>]")}
15659
15850
  `);
15660
- process.stdout.write(` ${c2.dim(" /endpoint http://localhost:11434 Ollama")}
15851
+ process.stdout.write(` ${c2.dim(" /endpoint http://127.0.0.1:11434 Ollama")}
15661
15852
  `);
15662
15853
  process.stdout.write(` ${c2.dim(" /endpoint https://llm.chutes.ai --auth cpk_... Chutes AI")}
15663
15854
  `);
@@ -15890,7 +16081,7 @@ var init_commands = __esm({
15890
16081
  import { existsSync as existsSync16, readFileSync as readFileSync13, readdirSync as readdirSync8 } from "node:fs";
15891
16082
  import { join as join23, basename as basename6 } from "node:path";
15892
16083
  import { execSync as execSync14 } from "node:child_process";
15893
- import { homedir as homedir9, platform, release } from "node:os";
16084
+ import { homedir as homedir9, platform as platform2, release } from "node:os";
15894
16085
  function getModelTier(modelName) {
15895
16086
  const m = modelName.toLowerCase();
15896
16087
  const sizeMatch = m.match(/\b(\d+)b\b/);
@@ -16030,7 +16221,7 @@ function getEnvironment(repoRoot) {
16030
16221
  const lines = [
16031
16222
  `Working directory: ${repoRoot}`,
16032
16223
  `Date: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`,
16033
- `Platform: ${platform()} ${release()}`,
16224
+ `Platform: ${platform2()} ${release()}`,
16034
16225
  `Node: ${process.version}`
16035
16226
  ];
16036
16227
  return lines.join("\n");
@@ -17371,7 +17562,7 @@ var init_carousel_descriptors = __esm({
17371
17562
  // packages/cli/dist/tui/voice.js
17372
17563
  import { existsSync as existsSync18, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9, readFileSync as readFileSync15, unlinkSync as unlinkSync3 } from "node:fs";
17373
17564
  import { join as join25 } from "node:path";
17374
- import { homedir as homedir10, tmpdir as tmpdir4, platform as platform2 } from "node:os";
17565
+ import { homedir as homedir10, tmpdir as tmpdir4, platform as platform3 } from "node:os";
17375
17566
  import { execSync as execSync15, spawn as nodeSpawn } from "node:child_process";
17376
17567
  import { createRequire } from "node:module";
17377
17568
  function voiceDir() {
@@ -17778,7 +17969,7 @@ var init_voice = __esm({
17778
17969
  });
17779
17970
  }
17780
17971
  getPlayCommand(path) {
17781
- const os = platform2();
17972
+ const os = platform3();
17782
17973
  if (os === "darwin")
17783
17974
  return ["afplay", path];
17784
17975
  if (os === "win32") {
@@ -21897,7 +22088,7 @@ var serve_exports = {};
21897
22088
  __export(serve_exports, {
21898
22089
  serveCommand: () => serveCommand
21899
22090
  });
21900
- import { spawn as spawn8 } from "node:child_process";
22091
+ import { spawn as spawn9 } from "node:child_process";
21901
22092
  async function serveCommand(opts, config) {
21902
22093
  const backendType = config.backendType;
21903
22094
  if (backendType === "ollama") {
@@ -21990,7 +22181,7 @@ async function serveVllm(opts, config) {
21990
22181
  }
21991
22182
  async function runVllmServer(args, verbose) {
21992
22183
  return new Promise((resolve19, reject) => {
21993
- const child = spawn8("python", args, {
22184
+ const child = spawn9("python", args, {
21994
22185
  stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
21995
22186
  env: { ...process.env }
21996
22187
  });
package/dist/launcher.cjs CHANGED
@@ -198,10 +198,26 @@ if (nodeVersion < 18) {
198
198
  }
199
199
  console.log("");
200
200
  console.log(" ┌─────────────────────────────────────────────────┐");
201
- console.log(" │ Done! Open a new terminal, then run: oa │");
201
+ console.log(" │ Done! Launching open-agents... │");
202
202
  console.log(" └─────────────────────────────────────────────────┘");
203
203
  console.log("");
204
204
  rl.close();
205
+
206
+ // Auto-source shell config and re-exec oa — no "open a new terminal" needed
207
+ var rcFile = shell.indexOf("zsh") !== -1 ? "~/.zshrc" : "~/.bashrc";
208
+ var relaunchCmd = 'export NVM_DIR="' + nvmDir + '" && ' +
209
+ '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" && ' +
210
+ "source " + rcFile + " 2>/dev/null; " +
211
+ "exec oa";
212
+ try {
213
+ childProcess.execSync(shell + " -c '" + relaunchCmd + "'", {
214
+ stdio: "inherit",
215
+ env: process.env,
216
+ });
217
+ } catch (e) {
218
+ // Fallback: tell user to open new terminal only if re-exec fails
219
+ console.log("\n If oa didn't launch, run: source " + rcFile + " && oa\n");
220
+ }
205
221
  process.exit(0);
206
222
  });
207
223
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.30.4",
3
+ "version": "0.30.5",
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",