myagent-ai 1.15.59 → 1.15.60

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 (3) hide show
  1. package/install/install.sh +27 -22
  2. package/package.json +1 -1
  3. package/start.js +108 -33
@@ -171,6 +171,23 @@ install_node() {
171
171
  exit 1
172
172
  }
173
173
 
174
+ # ── 找到 myagent-ai 命令路径 ──────────────────────────────
175
+ find_myagent_cmd() {
176
+ if command -v myagent-ai &>/dev/null; then
177
+ echo "myagent-ai"
178
+ return 0
179
+ fi
180
+ # npm bin -g 在新版 npm 中已废弃,使用 npm prefix -g
181
+ local npm_prefix
182
+ npm_prefix="$(npm prefix -g 2>/dev/null)" || return 1
183
+ local cmd_path="${npm_prefix}/bin/myagent-ai"
184
+ if [ -x "$cmd_path" ]; then
185
+ echo "$cmd_path"
186
+ return 0
187
+ fi
188
+ return 1
189
+ }
190
+
174
191
  # ── Main ─────────────────────────────────────────────────
175
192
  if ! $NO_DEPS; then
176
193
  check_python || install_python
@@ -188,18 +205,12 @@ success "$PKG_NAME installed"
188
205
 
189
206
  # 用 start.js 的 install 命令创建 venv 并安装全部 Python 依赖
190
207
  step "Installing Python dependencies ..."
191
- if command -v myagent-ai &>/dev/null; then
192
- myagent-ai install
208
+ myagent_cmd="$(find_myagent_cmd)"
209
+ if [ -n "$myagent_cmd" ]; then
210
+ "$myagent_cmd" install
193
211
  else
194
- # myagent-ai 不在 PATH 中,尝试直接调用
195
- local npm_bin
196
- npm_bin="$(npm bin -g 2>/dev/null)/myagent-ai"
197
- if [ -x "$npm_bin" ]; then
198
- "$npm_bin" install
199
- else
200
- err "myagent-ai 命令未找到,请重新打开终端后运行: myagent-ai install"
201
- exit 1
202
- fi
212
+ err "myagent-ai 命令未找到,请重新打开终端后运行: myagent-ai install"
213
+ exit 1
203
214
  fi
204
215
 
205
216
  echo ""
@@ -207,16 +218,10 @@ echo -e " ${BOLD}${SUCCESS}安装完成!${NC}"
207
218
  echo ""
208
219
 
209
220
  # 启动 Web 模式
210
- if command -v myagent-ai &>/dev/null; then
211
- info "启动中: myagent-ai web"
212
- myagent-ai web
221
+ myagent_cmd="$(find_myagent_cmd)"
222
+ if [ -n "$myagent_cmd" ]; then
223
+ info "启动中: $myagent_cmd web"
224
+ "$myagent_cmd" web
213
225
  else
214
- local npm_bin
215
- npm_bin="$(npm bin -g 2>/dev/null)/myagent-ai"
216
- if [ -x "$npm_bin" ]; then
217
- info "启动中: $npm_bin web"
218
- "$npm_bin" web
219
- else
220
- echo -e " 请重新打开终端后运行: ${ACCENT}myagent-ai web${NC}"
221
- fi
226
+ echo -e " 请重新打开终端后运行: ${ACCENT}myagent-ai web${NC}"
222
227
  fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myagent-ai",
3
- "version": "1.15.59",
3
+ "version": "1.15.60",
4
4
  "description": "本地桌面端执行型AI助手 - Open Interpreter 风格 | Local Desktop Execution-Oriented AI Assistant",
5
5
  "main": "main.py",
6
6
  "bin": {
package/start.js CHANGED
@@ -6,6 +6,11 @@
6
6
  * - install/reinstall: 创建 venv + 安装所有依赖
7
7
  * - web/cli/tray/server: 直接启动,不检查依赖
8
8
  * - uninstall: 卸载
9
+ *
10
+ * 安装策略:
11
+ * - 先尝试 pip install -r requirements.txt (批量安装)
12
+ * - 如果失败,逐包安装: 核心包失败=报错,可选包失败=跳过
13
+ * - 确保即使部分可选包编译失败,核心功能也能正常运行
9
14
  */
10
15
  "use strict";
11
16
 
@@ -17,6 +22,9 @@ const os = require("os");
17
22
  const IS_WIN = process.platform === "win32";
18
23
  const PKG_NAME = "myagent-ai";
19
24
 
25
+ // 核心依赖: 缺少任何一个就无法启动
26
+ const CORE_DEPS = ["openai", "aiohttp", "requests"];
27
+
20
28
  // ── 路径工具 ──────────────────────────────────────────────
21
29
 
22
30
  function getHome() { return os.homedir(); }
@@ -90,6 +98,12 @@ function getPipMirrorArgs() {
90
98
  return [];
91
99
  }
92
100
 
101
+ const MIRRORS = [
102
+ () => getPipMirrorArgs(),
103
+ () => ["-i", "https://mirrors.aliyun.com/pypi/simple/", "--trusted-host", "mirrors.aliyun.com"],
104
+ () => [],
105
+ ];
106
+
93
107
  // ── 虚拟环境 ──────────────────────────────────────────────
94
108
 
95
109
  function ensureVenv() {
@@ -120,7 +134,6 @@ function ensureVenv() {
120
134
  encoding: "utf8", stdio: "inherit", timeout: 60000,
121
135
  });
122
136
  } catch (_) {
123
- // Debian/Ubuntu: 尝试安装 venv 模块
124
137
  if (!IS_WIN) {
125
138
  try {
126
139
  execFileSync("sudo", ["apt-get", "install", "-y", "python3-venv"], {
@@ -147,61 +160,123 @@ function ensureVenv() {
147
160
  return getVenvPython(venvDir);
148
161
  }
149
162
 
150
- // ── 依赖安装(仅在 install/reinstall/首次运行时调用) ───
163
+ // ── 依赖安装 ──────────────────────────────────────────────
151
164
 
165
+ /**
166
+ * pip install 单个包,支持多镜像源重试
167
+ * @returns {boolean} 是否安装成功
168
+ */
169
+ function pipInstall(venvPython, pkgSpec, quiet) {
170
+ for (const getMirror of MIRRORS) {
171
+ try {
172
+ const args = ["-m", "pip", "install", "--disable-pip-version-check", ...getMirror()];
173
+ if (quiet) args.push("-q");
174
+ args.push(pkgSpec);
175
+ execFileSync(venvPython, args, {
176
+ encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 180000,
177
+ });
178
+ return true;
179
+ } catch (_) {}
180
+ }
181
+ return false;
182
+ }
183
+
184
+ /**
185
+ * 从 requirements.txt 解析包列表
186
+ * @returns {string[]} 如 ["openai>=1.12.0", "aiohttp>=3.9.0", ...]
187
+ */
188
+ function parseRequirements(reqFile) {
189
+ const content = fs.readFileSync(reqFile, "utf8");
190
+ return content
191
+ .split("\n")
192
+ .map(line => line.trim())
193
+ .filter(line => line && !line.startsWith("#") && !line.startsWith("-"));
194
+ }
195
+
196
+ /**
197
+ * 获取包名(去掉版本约束): "openai>=1.12.0" → "openai"
198
+ */
199
+ function pkgBaseName(spec) {
200
+ return spec.replace(/[<>=!~].*/, "").trim().toLowerCase();
201
+ }
202
+
203
+ /**
204
+ * 安装全部依赖 - 容错策略
205
+ *
206
+ * 1. 先尝试 pip install -r requirements.txt 批量安装
207
+ * 2. 如果失败,逐包安装:
208
+ * - 核心包 (openai/aiohttp/requests): 失败则报错退出
209
+ * - 可选包: 失败只 warn,不阻塞
210
+ * 3. 确保核心功能可用
211
+ */
152
212
  function installAllDeps(venvPython, pkgDir) {
153
213
  const reqFile = path.join(pkgDir, "requirements.txt");
154
214
  const mirrorArgs = getPipMirrorArgs();
155
215
  if (mirrorArgs.length) console.log(" 使用国内镜像源 (清华)");
156
216
 
157
217
  // 升级 pip
158
- try {
159
- execFileSync(venvPython, ["-m", "pip", "install", "--upgrade", "pip", "-q"], {
160
- encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 120000,
161
- });
162
- } catch (_) {}
218
+ pipInstall(venvPython, "--upgrade pip", true);
163
219
 
164
- // Linux: 预装 evdev
165
- if (!IS_WIN) {
166
- try {
167
- execFileSync(venvPython, ["-m", "pip", "install", "evdev-binary", "-q", "--disable-pip-version-check"], {
168
- encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 60000,
169
- });
170
- } catch (_) {}
171
- }
220
+ // Linux: 预装 evdev-binary (pynput 的依赖,避免编译 evdev)
221
+ if (!IS_WIN) pipInstall(venvPython, "evdev-binary", true);
172
222
 
173
- // 安装全部依赖
223
+ // 第一轮: 批量安装 requirements.txt
174
224
  if (fs.existsSync(reqFile)) {
175
- console.log(" 安装依赖 (可能需要几分钟)...");
225
+ console.log(" 安装依赖...");
176
226
  try {
177
227
  execFileSync(venvPython, ["-m", "pip", "install", "-r", reqFile, "--disable-pip-version-check", ...mirrorArgs], {
178
- encoding: "utf8", stdio: "inherit", timeout: 600000,
228
+ encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 600000,
179
229
  });
180
230
  console.log(" \x1b[32m✓\x1b[0m 全部依赖安装完成");
181
- return true;
182
- } catch (err) {
183
- console.log(` \x1b[33m安装失败: ${err.message.split("\n").pop().trim()}\x1b[0m`);
231
+ return { ok: true, failedOptional: [] };
232
+ } catch (_) {
233
+ // 批量安装失败,进入逐包容错模式
234
+ console.log(" \x1b[33m部分依赖安装遇到问题,切换到逐包安装...\x1b[0m");
184
235
  }
185
236
  }
186
237
 
187
- // 回退: 核心依赖
188
- const CORE = [
238
+ // 第二轮: 逐包安装
239
+ const packages = fs.existsSync(reqFile) ? parseRequirements(reqFile) : [
189
240
  "openai>=1.12.0", "aiohttp>=3.9.0", "requests>=2.31.0",
190
241
  "duckduckgo-search>=6.0.0", "beautifulsoup4>=4.12.0",
191
242
  "psutil>=5.9.0", "Pillow>=10.0.0", "edge-tts>=6.1.0",
192
243
  "anthropic>=0.18.0",
193
244
  ];
194
- for (const mirrors of [mirrorArgs, ["-i", "https://mirrors.aliyun.com/pypi/simple/", "--trusted-host", "mirrors.aliyun.com"]]) {
195
- try {
196
- console.log(" 尝试安装核心依赖...");
197
- execFileSync(venvPython, ["-m", "pip", "install", "-q", "--disable-pip-version-check", ...mirrors, ...CORE], {
198
- encoding: "utf8", stdio: "inherit", timeout: 300000,
199
- });
200
- console.log(" \x1b[32m✓\x1b[0m 核心依赖安装完成");
201
- return true;
202
- } catch (_) {}
245
+
246
+ const failedCore = [];
247
+ const failedOptional = [];
248
+
249
+ for (const pkg of packages) {
250
+ const baseName = pkgBaseName(pkg);
251
+ const isCore = CORE_DEPS.includes(baseName);
252
+
253
+ if (pipInstall(venvPython, pkg, true)) continue;
254
+
255
+ // 安装失败
256
+ if (isCore) {
257
+ failedCore.push(pkg);
258
+ } else {
259
+ failedOptional.push(pkg);
260
+ }
203
261
  }
204
- return false;
262
+
263
+ // 核心依赖失败 = 无法运行
264
+ if (failedCore.length > 0) {
265
+ console.error(`\x1b[31m ✗ 核心依赖安装失败: ${failedCore.join(", ")}\x1b[0m`);
266
+ console.error(" 请手动安装: " + failedCore.map(p => `pip install ${p}`).join(" && "));
267
+ process.exit(1);
268
+ }
269
+
270
+ // 可选依赖失败 = 只提示
271
+ if (failedOptional.length > 0) {
272
+ console.log(` \x1b[33m⚠ 以下可选包安装失败(不影响核心功能):\x1b[0m`);
273
+ for (const pkg of failedOptional) {
274
+ console.log(` \x1b[33m- ${pkg}\x1b[0m`);
275
+ }
276
+ }
277
+
278
+ console.log(" \x1b[32m✓\x1b[0m 核心依赖已就绪");
279
+ return { ok: true, failedOptional };
205
280
  }
206
281
 
207
282
  // 标记依赖已安装