open-agents-ai 0.23.0 → 0.23.2

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
@@ -6961,20 +6961,45 @@ var init_desktop_click = __esm({
6961
6961
  durationMs: performance.now() - start
6962
6962
  };
6963
6963
  }
6964
- const { vl } = await import("moondream");
6965
- const apiKey = process.env["MOONDREAM_API_KEY"];
6966
- const endpoint = process.env["MOONDREAM_ENDPOINT"];
6967
- let client;
6968
- if (apiKey) {
6969
- client = new vl({ apiKey });
6970
- } else if (endpoint) {
6971
- client = new vl({ endpoint });
6972
- } else {
6973
- client = new vl({ endpoint: "http://localhost:2020/v1" });
6964
+ let points = [];
6965
+ let visionWorked = false;
6966
+ try {
6967
+ const { vl } = await import("moondream");
6968
+ const apiKey = process.env["MOONDREAM_API_KEY"];
6969
+ const endpoint = process.env["MOONDREAM_ENDPOINT"];
6970
+ let client;
6971
+ if (apiKey) {
6972
+ client = new vl({ apiKey });
6973
+ } else if (endpoint) {
6974
+ client = new vl({ endpoint });
6975
+ } else {
6976
+ client = new vl({ endpoint: "http://localhost:2020/v1" });
6977
+ }
6978
+ const imageBuffer = readFileSync11(screenshotPath);
6979
+ const pointResult = await client.point({ image: imageBuffer, object: target });
6980
+ points = pointResult.points ?? [];
6981
+ visionWorked = true;
6982
+ } catch {
6983
+ }
6984
+ if (!visionWorked) {
6985
+ const hints = [
6986
+ `(Moondream vision not available \u2014 cannot locate "${target}" on screen)`,
6987
+ `Screenshot saved: ${screenshotPath}`,
6988
+ `Screen: ${dims.width}x${dims.height}`,
6989
+ "",
6990
+ "Use shell commands to interact with the desktop instead:",
6991
+ " xdotool search --name 'pattern' \u2014 find windows by title",
6992
+ " xdotool key 'ctrl+s' \u2014 send keyboard shortcuts",
6993
+ " xdotool mousemove X Y click 1 \u2014 click at known coordinates",
6994
+ " wmctrl -a 'window title' \u2014 activate a window by name",
6995
+ " xdg-open <url> \u2014 open a URL in the default browser"
6996
+ ];
6997
+ return {
6998
+ success: true,
6999
+ output: hints.join("\n"),
7000
+ durationMs: performance.now() - start
7001
+ };
6974
7002
  }
6975
- const imageBuffer = readFileSync11(screenshotPath);
6976
- const pointResult = await client.point({ image: imageBuffer, object: target });
6977
- const points = pointResult.points ?? [];
6978
7003
  if (points.length === 0) {
6979
7004
  return {
6980
7005
  success: false,
@@ -7066,37 +7091,62 @@ Screenshot: ${screenshotPath}`,
7066
7091
  captureScreenshot(screenshotPath);
7067
7092
  const dims = getImageDimensions2(screenshotPath);
7068
7093
  const imageBuffer = readFileSync11(screenshotPath);
7069
- const { vl } = await import("moondream");
7070
- const apiKey = process.env["MOONDREAM_API_KEY"];
7071
- const endpoint = process.env["MOONDREAM_ENDPOINT"];
7072
- let client;
7073
- if (apiKey) {
7074
- client = new vl({ apiKey });
7075
- } else if (endpoint) {
7076
- client = new vl({ endpoint });
7077
- } else {
7078
- client = new vl({ endpoint: "http://localhost:2020/v1" });
7079
- }
7080
7094
  const parts = [];
7081
- if (question) {
7082
- const result = await client.query({ image: imageBuffer, question });
7083
- const answer = typeof result.answer === "string" ? result.answer : "(streaming not supported)";
7084
- parts.push(`Q: ${question}`);
7085
- parts.push(`A: ${answer}`);
7086
- } else {
7087
- const result = await client.caption({ image: imageBuffer, length });
7088
- const caption = typeof result.caption === "string" ? result.caption : "(streaming not supported)";
7089
- parts.push(`Desktop description:
7095
+ let visionWorked = false;
7096
+ try {
7097
+ const { vl } = await import("moondream");
7098
+ const apiKey = process.env["MOONDREAM_API_KEY"];
7099
+ const endpoint = process.env["MOONDREAM_ENDPOINT"];
7100
+ let client;
7101
+ if (apiKey) {
7102
+ client = new vl({ apiKey });
7103
+ } else if (endpoint) {
7104
+ client = new vl({ endpoint });
7105
+ } else {
7106
+ client = new vl({ endpoint: "http://localhost:2020/v1" });
7107
+ }
7108
+ if (question) {
7109
+ const result = await client.query({ image: imageBuffer, question });
7110
+ const answer = typeof result.answer === "string" ? result.answer : "(streaming not supported)";
7111
+ parts.push(`Q: ${question}`);
7112
+ parts.push(`A: ${answer}`);
7113
+ } else {
7114
+ const result = await client.caption({ image: imageBuffer, length });
7115
+ const caption = typeof result.caption === "string" ? result.caption : "(streaming not supported)";
7116
+ parts.push(`Desktop description:
7090
7117
  ${caption}`);
7118
+ }
7119
+ visionWorked = true;
7120
+ } catch {
7121
+ }
7122
+ if (!visionWorked) {
7123
+ let ocrText = "";
7124
+ try {
7125
+ ocrText = execSync11(`tesseract ${JSON.stringify(screenshotPath)} stdout 2>/dev/null`, {
7126
+ encoding: "utf8",
7127
+ timeout: 15e3
7128
+ }).trim();
7129
+ } catch {
7130
+ }
7131
+ if (ocrText) {
7132
+ parts.push("(Moondream vision not available \u2014 using OCR text extraction)");
7133
+ parts.push(`
7134
+ Visible text on screen:
7135
+ ${ocrText}`);
7136
+ } else {
7137
+ parts.push("(Moondream vision not available, OCR failed)");
7138
+ parts.push("Screenshot captured but cannot describe contents.");
7139
+ parts.push("Use shell commands to check window state instead:");
7140
+ parts.push(" xdotool getactivewindow getwindowname \u2014 get active window title");
7141
+ parts.push(" wmctrl -l \u2014 list all open windows");
7142
+ parts.push(" xdg-open <url> \u2014 open a URL in the default browser");
7143
+ }
7091
7144
  }
7092
7145
  if (dims) {
7093
7146
  parts.push(`
7094
7147
  Screen: ${dims.width}x${dims.height}`);
7095
7148
  }
7096
7149
  parts.push(`Screenshot: ${screenshotPath}`);
7097
- const base64 = imageBuffer.toString("base64");
7098
- parts.push(`
7099
- [IMAGE_BASE64:image/png:${base64}]`);
7100
7150
  return {
7101
7151
  success: true,
7102
7152
  output: parts.join("\n"),
package/dist/launcher.cjs CHANGED
@@ -1,29 +1,32 @@
1
1
  #!/usr/bin/env node
2
2
  // Node version gate — uses only ES5 syntax so it parses on any Node version.
3
- // On old Node: offers to install Node 20 via nvm with y/n prompts.
3
+ // On old Node: walks through nvm install, then Node 20, then reinstall.
4
4
  var nodeVersion = parseInt(process.versions.node, 10);
5
5
 
6
6
  if (nodeVersion < 18) {
7
7
  var os = require("os");
8
8
  var path = require("path");
9
+ var fs = require("fs");
9
10
  var childProcess = require("child_process");
10
11
  var readline = require("readline");
11
12
 
12
13
  var platform = os.platform();
13
14
  var arch = os.arch();
14
15
 
15
- console.log(
16
- "\n open-agents requires Node.js >= 18 (you have " + process.version + ")" +
17
- "\n Platform: " + platform + "/" + arch + "\n"
18
- );
16
+ console.log("");
17
+ console.log(" ┌─────────────────────────────────────────────────┐");
18
+ console.log(" │ open-agents Node.js Upgrade │");
19
+ console.log(" └─────────────────────────────────────────────────┘");
20
+ console.log("");
21
+ console.log(" Your Node.js: " + process.version);
22
+ console.log(" Required: >= 18.0.0");
23
+ console.log(" Platform: " + platform + "/" + arch);
24
+ console.log("");
19
25
 
20
- // Check if nvm is already installed
26
+ // Detect if nvm is already installed
21
27
  var nvmDir = process.env.NVM_DIR || path.join(os.homedir(), ".nvm");
22
28
  var hasNvm = false;
23
- try {
24
- require("fs").statSync(path.join(nvmDir, "nvm.sh"));
25
- hasNvm = true;
26
- } catch (e) {}
29
+ try { fs.statSync(path.join(nvmDir, "nvm.sh")); hasNvm = true; } catch (e) {}
27
30
 
28
31
  var rl = readline.createInterface({ input: process.stdin, output: process.stdout });
29
32
 
@@ -33,10 +36,10 @@ if (nodeVersion < 18) {
33
36
  });
34
37
  }
35
38
 
36
- function run(cmd, opts) {
39
+ function run(cmd) {
37
40
  console.log(" $ " + cmd);
38
41
  try {
39
- childProcess.execSync(cmd, Object.assign({ stdio: "inherit" }, opts || {}));
42
+ childProcess.execSync(cmd, { stdio: "inherit" });
40
43
  return true;
41
44
  } catch (e) {
42
45
  console.error(" Command failed: " + (e.message || e));
@@ -44,70 +47,123 @@ if (nodeVersion < 18) {
44
47
  }
45
48
  }
46
49
 
47
- function installNode() {
48
- if (!hasNvm) {
49
- console.log("\n nvm not found. Installing nvm first...\n");
50
+ function bail(msg) {
51
+ console.log(msg);
52
+ rl.close();
53
+ process.exit(1);
54
+ }
55
+
56
+ function doInstallNvm(next) {
57
+ if (hasNvm) {
58
+ console.log(" nvm found at " + nvmDir);
59
+ console.log("");
60
+ next();
61
+ return;
62
+ }
63
+ ask(" nvm is not installed. Install nvm now? [Y/n] ", function(a) {
64
+ if (a === "n" || a === "no") {
65
+ bail(
66
+ "\n Install nvm manually:\n" +
67
+ " curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash\n" +
68
+ " source ~/.bashrc\n" +
69
+ " nvm install 20\n" +
70
+ " npm i -g open-agents-ai\n"
71
+ );
72
+ return;
73
+ }
74
+ console.log("");
50
75
  var ok = run("curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash");
51
76
  if (!ok) {
52
- console.error("\n nvm install failed. Install manually:");
53
- console.error(" https://github.com/nvm-sh/nvm#installing-and-updating\n");
54
- rl.close();
55
- process.exit(1);
77
+ bail("\n nvm install failed. See https://github.com/nvm-sh/nvm#installing-and-updating\n");
78
+ return;
56
79
  }
57
- // Re-source nvm for this session
58
80
  nvmDir = process.env.NVM_DIR || path.join(os.homedir(), ".nvm");
59
- } else {
60
- console.log("\n nvm found at " + nvmDir + "\n");
61
- }
62
-
63
- // nvm is a shell function, so we run through bash
64
- var shell = process.env.SHELL || "/bin/bash";
65
- var nvmCmd = 'export NVM_DIR="' + nvmDir + '" && ' +
66
- '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" && ' +
67
- "nvm install 20 && nvm use 20 && nvm alias default 20";
81
+ hasNvm = true;
82
+ console.log("");
83
+ next();
84
+ });
85
+ }
68
86
 
69
- console.log(" Installing Node.js 20...\n");
70
- var ok = run(shell + ' -c \'' + nvmCmd + "'");
71
- if (!ok) {
72
- console.error("\n Node 20 install failed.\n");
73
- rl.close();
74
- process.exit(1);
75
- }
87
+ function doInstallNode(next) {
88
+ ask(" Install Node.js 20 via nvm? [Y/n] ", function(a) {
89
+ if (a === "n" || a === "no") {
90
+ bail(
91
+ "\n Install manually:\n" +
92
+ " nvm install 20 && nvm alias default 20\n" +
93
+ " npm i -g open-agents-ai\n"
94
+ );
95
+ return;
96
+ }
97
+ console.log("");
98
+ var shell = process.env.SHELL || "/bin/bash";
99
+ var cmd = 'export NVM_DIR="' + nvmDir + '" && ' +
100
+ '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" && ' +
101
+ "nvm install 20 && nvm use 20 && nvm alias default 20";
102
+ var ok = run(shell + " -c '" + cmd + "'");
103
+ if (!ok) {
104
+ bail("\n Node 20 install failed.\n");
105
+ return;
106
+ }
107
+ console.log("");
108
+ next();
109
+ });
110
+ }
76
111
 
77
- // Now reinstall open-agents under the new Node
78
- console.log("\n Node 20 installed. Reinstalling open-agents...\n");
79
- var reinstallCmd = 'export NVM_DIR="' + nvmDir + '" && ' +
80
- '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" && ' +
81
- "npm i -g open-agents-ai";
82
- var ok2 = run(shell + ' -c \'' + reinstallCmd + "'");
83
- if (!ok2) {
84
- console.error("\n Reinstall failed. After opening a new terminal, run:");
85
- console.error(" npm i -g open-agents-ai\n");
112
+ function doReinstall() {
113
+ ask(" Reinstall open-agents under Node 20? [Y/n] ", function(a) {
114
+ if (a === "n" || a === "no") {
115
+ console.log(
116
+ "\n Open a new terminal, then run:\n" +
117
+ " npm i -g open-agents-ai\n"
118
+ );
119
+ rl.close();
120
+ process.exit(0);
121
+ return;
122
+ }
123
+ console.log("");
124
+ var shell = process.env.SHELL || "/bin/bash";
125
+ var cmd = 'export NVM_DIR="' + nvmDir + '" && ' +
126
+ '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" && ' +
127
+ "nvm use 20 && npm i -g open-agents-ai";
128
+ var ok = run(shell + " -c '" + cmd + "'");
129
+ if (!ok) {
130
+ console.log(
131
+ "\n Reinstall failed. Open a new terminal, then run:\n" +
132
+ " npm i -g open-agents-ai\n"
133
+ );
134
+ rl.close();
135
+ process.exit(1);
136
+ return;
137
+ }
138
+ console.log("");
139
+ console.log(" ┌─────────────────────────────────────────────────┐");
140
+ console.log(" │ Done! Open a new terminal, then run: oa │");
141
+ console.log(" └─────────────────────────────────────────────────┘");
142
+ console.log("");
86
143
  rl.close();
87
- process.exit(1);
88
- }
89
-
90
- console.log(
91
- "\n Done! Open a new terminal (or run: source ~/.bashrc) then run:" +
92
- "\n oa\n"
93
- );
94
- rl.close();
95
- process.exit(0);
144
+ process.exit(0);
145
+ });
96
146
  }
97
147
 
98
- ask(" Install Node.js 20 now? [Y/n] ", function(answer) {
99
- if (answer === "n" || answer === "no") {
100
- console.log(
148
+ // Walk through the steps
149
+ ask(" Upgrade to Node.js 20 now? [Y/n] ", function(a) {
150
+ if (a === "n" || a === "no") {
151
+ bail(
101
152
  "\n To install manually:\n" +
102
153
  " curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash\n" +
103
154
  " source ~/.bashrc\n" +
104
155
  " nvm install 20\n" +
156
+ " nvm alias default 20\n" +
105
157
  " npm i -g open-agents-ai\n"
106
158
  );
107
- rl.close();
108
- process.exit(1);
159
+ return;
109
160
  }
110
- installNode();
161
+ console.log("");
162
+ doInstallNvm(function() {
163
+ doInstallNode(function() {
164
+ doReinstall();
165
+ });
166
+ });
111
167
  });
112
168
  } else {
113
169
  // Node >= 18 — load the ESM bundle
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.23.0",
3
+ "version": "0.23.2",
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",