myagent-ai 1.47.10 → 1.47.11

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.
@@ -214,15 +214,21 @@ def _ensure_display() -> Optional[Dict[str, Any]]:
214
214
  """
215
215
  确保有可用的 X11 显示,供浏览器有头模式使用。
216
216
 
217
- 优先级:
218
- 1. 复用 VNC 远程桌面的 Xvfb 显示(用户可在 VNC 中看到浏览器操作)
219
- 2. 自动启动 VNC(含 Xvfb + x11vnc + websockify)
220
- 3. VNC 不可用时独立启动 Xvfb
217
+ Termux+Ubuntu 环境: 只支持 VNC,无其他 fallback
218
+ Termux 容器环境: VNC > 独立 Xvfb 降级
221
219
 
222
220
  Returns:
223
221
  {"display": ":99", "vnc": True/False, "xvfb_standalone": True/False}
224
222
  失败返回 None
225
223
  """
224
+ # 检测是否为 Termux 环境
225
+ _is_termux = False
226
+ try:
227
+ from core.env_detect import is_termux
228
+ _is_termux = is_termux()
229
+ except ImportError:
230
+ pass
231
+
226
232
  # 1. 尝试复用 VNC 远程桌面
227
233
  try:
228
234
  from core.vnc_manager import get_vnc_manager
@@ -240,8 +246,6 @@ def _ensure_display() -> Optional[Dict[str, Any]]:
240
246
  import asyncio
241
247
  loop = asyncio.get_event_loop()
242
248
  if loop.is_running():
243
- # 在已有事件循环中,用 run_until_complete 不行,
244
- # 创建 task 等待完成
245
249
  import concurrent.futures
246
250
  with concurrent.futures.ThreadPoolExecutor() as pool:
247
251
  result = pool.submit(asyncio.run, vnc.start()).result(timeout=30)
@@ -263,9 +267,15 @@ def _ensure_display() -> Optional[Dict[str, Any]]:
263
267
  except Exception as e:
264
268
  logger.warning(f"VNC 检测异常: {e}")
265
269
 
266
- # 2. VNC 不可用 独立启动 Xvfb
267
- # [v1.47.10] 用 display :100 避免和 VNC 的 :99 冲突
268
- # 如果 VNC 刚被杀但锁文件还在,用 :99 会 returncode=1
270
+ # ── Termux+Ubuntu: VNC 是唯一方式,不允许其他 fallback ──
271
+ if _is_termux:
272
+ logger.error(
273
+ "Termux+Ubuntu 环境仅支持通过 VNC 启动浏览器,"
274
+ "VNC 启动失败。请检查 VNC 配置或手动启动 VNC 远程桌面。"
275
+ )
276
+ return None
277
+
278
+ # 2. 非 Termux 容器环境 → 独立启动 Xvfb 作为 fallback
269
279
  xvfb_display = _start_xvfb(display_num=100)
270
280
  if xvfb_display:
271
281
  return {"display": xvfb_display, "vnc": False, "xvfb_standalone": True}
@@ -561,17 +571,24 @@ class StealthBrowser:
561
571
  logger.info("桌面环境,使用系统 Chrome 原生参数")
562
572
 
563
573
  # ── 无显示环境处理 ──
564
- # 使用 is_desktop() 判断是否为桌面环境(Windows/macOS/Linux有真实显示器)
565
- # 桌面环境直接使用系统 Chrome,不需要 VNC/Xvfb
566
- # 仅在非桌面的 Linux(容器/Termux)环境中才尝试 VNC/Xvfb
574
+ # 桌面环境 (Windows/macOS/Linux有真实显示器): 直接用系统 Chrome
575
+ # Termux+Ubuntu: 仅支持 VNC,不降级到 headless
576
+ # Termux 容器: VNC > Xvfb > headless 降级
577
+ _is_termux_env = False
578
+ try:
579
+ from core.env_detect import is_termux
580
+ _is_termux_env = is_termux()
581
+ except ImportError:
582
+ pass
583
+
567
584
  if not self._headless:
568
585
  try:
569
586
  from core.env_detect import is_desktop
570
587
  if is_desktop():
571
- # 桌面环境(Windows/macOS/Linux有真实显示器): 直接用系统 Chrome
588
+ # 桌面环境: 直接用系统 Chrome
572
589
  logger.info("桌面环境,直接使用系统浏览器,跳过 VNC/Xvfb")
573
590
  else:
574
- # 非桌面 Linux(容器/Termux): 尝试 VNC > Xvfb > headless 降级
591
+ # 非桌面环境 (容器/Termux): 通过 _ensure_display() 获取显示
575
592
  display = _ensure_display()
576
593
  if display:
577
594
  self._vnc_used = display.get("vnc", False)
@@ -579,6 +596,17 @@ class StealthBrowser:
579
596
  if self._vnc_used:
580
597
  logger.info(f"复用 VNC 远程桌面显示 ({display['display']}),可在 VNC 中查看浏览器操作")
581
598
  else:
599
+ # ── Termux+Ubuntu: VNC 失败 → 直接报错,不降级 headless ──
600
+ if _is_termux_env:
601
+ return SkillResult(
602
+ success=False,
603
+ error=(
604
+ "Termux+Ubuntu 环境仅支持通过 VNC 启动浏览器,"
605
+ "VNC 启动失败。请先启动 VNC 远程桌面,"
606
+ "或通过 Web 管理面板打开 VNC 后再使用浏览器功能。"
607
+ ),
608
+ )
609
+ # ── 非 Termux 容器: 降级到 headless ──
582
610
  self._headless = True
583
611
  logger.warning(
584
612
  "无显示环境且 VNC/Xvfb 均不可用,自动降级为 headless 模式"
@@ -591,10 +619,39 @@ class StealthBrowser:
591
619
  self._vnc_used = display.get("vnc", False)
592
620
  self._xvfb_started_by_us = display.get("xvfb_standalone", False)
593
621
  else:
622
+ if _is_termux_env:
623
+ return SkillResult(
624
+ success=False,
625
+ error=(
626
+ "Termux+Ubuntu 环境仅支持通过 VNC 启动浏览器,"
627
+ "VNC 启动失败。请先启动 VNC 远程桌面后再使用浏览器功能。"
628
+ ),
629
+ )
594
630
  self._headless = True
595
631
  logger.warning(
596
632
  "无 DISPLAY 环境且 VNC/Xvfb 均不可用,自动降级为 headless 模式"
597
633
  )
634
+ else:
635
+ # headless=True 被显式请求,但 Termux 环境下仍强制使用 VNC
636
+ # 因为 headless Chromium 在 Termux 下容易被 OOM Kill
637
+ if _is_termux_env:
638
+ logger.info("Termux+Ubuntu 环境: 忽略 headless 请求,强制使用 VNC 模式")
639
+ self._headless = False
640
+ display = _ensure_display()
641
+ if display:
642
+ self._vnc_used = display.get("vnc", False)
643
+ self._xvfb_started_by_us = display.get("xvfb_standalone", False)
644
+ if self._vnc_used:
645
+ logger.info(f"Termux+Ubuntu: 已通过 VNC 获取显示 ({display['display']})")
646
+ else:
647
+ return SkillResult(
648
+ success=False,
649
+ error=(
650
+ "Termux+Ubuntu 环境仅支持通过 VNC 启动浏览器,"
651
+ "VNC 启动失败。headless 模式在此环境下不可用(容易被 OOM Kill)。"
652
+ "请先启动 VNC 远程桌面后再使用浏览器功能。"
653
+ ),
654
+ )
598
655
 
599
656
  # 无头模式(co.headless() 内部设置 --headless=new)
600
657
  if self._headless:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myagent-ai",
3
- "version": "1.47.10",
3
+ "version": "1.47.11",
4
4
  "description": "本地桌面端执行型AI助手 - Open Interpreter 风格 | Local Desktop Execution-Oriented AI Assistant",
5
5
  "main": "main.py",
6
6
  "bin": {