myagent-ai 1.20.9 → 1.20.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.
Files changed (59) hide show
  1. package/agents/main_agent.py +37 -2
  2. package/core/vnc_manager.py +18 -6
  3. package/data/novnc/lib/base64.js +100 -0
  4. package/data/novnc/lib/crypto/aes.js +481 -0
  5. package/data/novnc/lib/crypto/bigint.js +41 -0
  6. package/data/novnc/lib/crypto/crypto.js +109 -0
  7. package/data/novnc/lib/crypto/des.js +374 -0
  8. package/data/novnc/lib/crypto/dh.js +81 -0
  9. package/data/novnc/lib/crypto/md5.js +97 -0
  10. package/data/novnc/lib/crypto/rsa.js +312 -0
  11. package/data/novnc/lib/decoders/copyrect.js +40 -0
  12. package/data/novnc/lib/decoders/hextile.js +195 -0
  13. package/data/novnc/lib/decoders/jpeg.js +175 -0
  14. package/data/novnc/lib/decoders/raw.js +66 -0
  15. package/data/novnc/lib/decoders/rre.js +52 -0
  16. package/data/novnc/lib/decoders/tight.js +363 -0
  17. package/data/novnc/lib/decoders/tightpng.js +51 -0
  18. package/data/novnc/lib/decoders/zrle.js +192 -0
  19. package/data/novnc/lib/deflator.js +88 -0
  20. package/data/novnc/lib/display.js +527 -0
  21. package/data/novnc/lib/encodings.js +63 -0
  22. package/data/novnc/lib/inflator.js +77 -0
  23. package/data/novnc/lib/input/domkeytable.js +313 -0
  24. package/data/novnc/lib/input/fixedkeys.js +127 -0
  25. package/data/novnc/lib/input/gesturehandler.js +573 -0
  26. package/data/novnc/lib/input/keyboard.js +292 -0
  27. package/data/novnc/lib/input/keysym.js +878 -0
  28. package/data/novnc/lib/input/keysymdef.js +1351 -0
  29. package/data/novnc/lib/input/util.js +217 -0
  30. package/data/novnc/lib/input/vkeys.js +121 -0
  31. package/data/novnc/lib/input/xtscancodes.js +343 -0
  32. package/data/novnc/lib/ra2.js +535 -0
  33. package/data/novnc/lib/rfb.js +3225 -0
  34. package/data/novnc/lib/util/browser.js +147 -0
  35. package/data/novnc/lib/util/cursor.js +269 -0
  36. package/data/novnc/lib/util/element.js +41 -0
  37. package/data/novnc/lib/util/events.js +133 -0
  38. package/data/novnc/lib/util/eventtarget.js +53 -0
  39. package/data/novnc/lib/util/int.js +21 -0
  40. package/data/novnc/lib/util/logging.js +56 -0
  41. package/data/novnc/lib/util/strings.js +36 -0
  42. package/data/novnc/lib/vendor/pako/lib/utils/common.js +55 -0
  43. package/data/novnc/lib/vendor/pako/lib/zlib/adler32.js +29 -0
  44. package/data/novnc/lib/vendor/pako/lib/zlib/constants.js +47 -0
  45. package/data/novnc/lib/vendor/pako/lib/zlib/crc32.js +35 -0
  46. package/data/novnc/lib/vendor/pako/lib/zlib/deflate.js +1721 -0
  47. package/data/novnc/lib/vendor/pako/lib/zlib/gzheader.js +41 -0
  48. package/data/novnc/lib/vendor/pako/lib/zlib/inffast.js +327 -0
  49. package/data/novnc/lib/vendor/pako/lib/zlib/inflate.js +1602 -0
  50. package/data/novnc/lib/vendor/pako/lib/zlib/inftrees.js +310 -0
  51. package/data/novnc/lib/vendor/pako/lib/zlib/messages.js +25 -0
  52. package/data/novnc/lib/vendor/pako/lib/zlib/trees.js +1150 -0
  53. package/data/novnc/lib/vendor/pako/lib/zlib/zstream.js +30 -0
  54. package/data/novnc/lib/websock.js +395 -0
  55. package/main.py +6 -0
  56. package/package.json +1 -1
  57. package/skills/agent_tool_skill.py +113 -0
  58. package/web/api_server.py +27 -40
  59. package/web/ui/chat/chat_main.js +15 -2
@@ -1669,6 +1669,7 @@ class MainAgent(BaseAgent):
1669
1669
  _media_type = "audio" if tool_name == "playaudio" else "video"
1670
1670
  _embed_url = None
1671
1671
  _embed_title = params.get("title", "")
1672
+ _fallback_link = None # [v1.20.10] 无法嵌入时提供外部链接
1672
1673
 
1673
1674
  if _media_url:
1674
1675
  # 在线链接 — 提取嵌入式播放 URL
@@ -1679,6 +1680,21 @@ class MainAgent(BaseAgent):
1679
1680
  if _yt_match:
1680
1681
  _embed_url = f"https://www.youtube.com/embed/{_yt_match.group(1)}"
1681
1682
  _embed_title = _embed_title or "YouTube 视频"
1683
+ # YouTube Music 播放列表: https://music.youtube.com/playlist?list=xxx
1684
+ elif 'music.youtube.com' in _url_lower:
1685
+ _ym_match = re.search(r'list=([\w-]+)', _media_url)
1686
+ if _ym_match:
1687
+ _embed_url = f"https://music.youtube.com/embed?list={_ym_match.group(1)}&layout=full"
1688
+ _embed_title = _embed_title or "YouTube Music"
1689
+ else:
1690
+ # 单曲: https://music.youtube.com/watch?v=xxx
1691
+ _ymv_match = re.search(r'watch\?v=([\w-]+)', _media_url)
1692
+ if _ymv_match:
1693
+ _embed_url = f"https://music.youtube.com/embed/{_ymv_match.group(1)}"
1694
+ _embed_title = _embed_title or "YouTube Music"
1695
+ else:
1696
+ _fallback_link = _media_url
1697
+ _embed_title = _embed_title or "YouTube Music"
1682
1698
  # Bilibili: https://www.bilibili.com/video/BVxxx 或 b23.tv/xxx
1683
1699
  elif 'bilibili.com' in _url_lower or 'b23.tv' in _url_lower:
1684
1700
  _bv_match = re.search(r'bilibili\.com/video/(BV[\w]+)', _media_url)
@@ -1690,8 +1706,14 @@ class MainAgent(BaseAgent):
1690
1706
  _embed_title = _embed_title or "B站视频"
1691
1707
  # QQ音乐: https://y.qq.com/n/ryqq/songDetail/xxx
1692
1708
  elif 'y.qq.com' in _url_lower:
1693
- _embed_url = _media_url
1694
- _embed_title = _embed_title or "QQ音乐"
1709
+ # QQ音乐支持 outchain player
1710
+ _qq_match = re.search(r'songDetail/(\w+)', _media_url)
1711
+ if _qq_match:
1712
+ _embed_url = f"https://y.qq.com/n/ryqq/songDetail/{_qq_match.group(1)}"
1713
+ _embed_title = _embed_title or "QQ音乐"
1714
+ else:
1715
+ _embed_url = _media_url
1716
+ _embed_title = _embed_title or "QQ音乐"
1695
1717
  # 网易云音乐: https://music.163.com/song?id=xxx
1696
1718
  elif 'music.163.com' in _url_lower:
1697
1719
  _song_match = re.search(r'music\.163\.com.*[?&]id=(\d+)', _media_url)
@@ -1723,6 +1745,19 @@ class MainAgent(BaseAgent):
1723
1745
  })
1724
1746
  result = {"success": True, "output": f"已嵌入{_embed_title}播放器: {_media_url}"}
1725
1747
 
1748
+ elif _fallback_link and stream_callback:
1749
+ # [v1.20.10] 无法嵌入但提供外部链接 — 发送链接卡片
1750
+ stream_callback({
1751
+ "type": "v2_media",
1752
+ "data": {
1753
+ "media_type": _media_type,
1754
+ "embed_url": "", # 空 embed_url 告诉前端渲染链接
1755
+ "title": _embed_title,
1756
+ "original_url": _fallback_link,
1757
+ }
1758
+ })
1759
+ result = {"success": True, "output": f"已提供{_embed_title}链接(不支持嵌入播放): {_fallback_link}"}
1760
+
1726
1761
  elif _media_file:
1727
1762
  # 本地文件 — 使用 file_send 发送文件,前端渲染内嵌播放器
1728
1763
  from pathlib import Path as _P
@@ -335,15 +335,23 @@ class VNCManager:
335
335
  """查找 noVNC web 文件目录
336
336
 
337
337
  搜索顺序:
338
- 1. /usr/share/novnc (apt 安装)
339
- 2. /usr/local/share/novnc
340
- 3. pip 安装的 websockify 自带 novnc
338
+ 1. 项目内置 noVNC (data/novnc/)
339
+ 2. /usr/share/novnc (apt 安装)
340
+ 3. /usr/local/share/novnc
341
+ 4. pip 安装的 websockify 自带 novnc
341
342
  """
342
- search_paths = [
343
+ search_paths = []
344
+
345
+ # [v1.20.9] 优先搜索项目内置 noVNC
346
+ _builtin_novnc = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'data', 'novnc')
347
+ if os.path.isdir(_builtin_novnc):
348
+ search_paths.append(_builtin_novnc)
349
+
350
+ search_paths.extend([
343
351
  "/usr/share/novnc",
344
352
  "/usr/local/share/novnc",
345
353
  "/opt/novnc",
346
- ]
354
+ ])
347
355
 
348
356
  # 也搜索 pip 安装路径
349
357
  try:
@@ -362,12 +370,16 @@ class VNCManager:
362
370
 
363
371
  for path in search_paths:
364
372
  if os.path.isdir(path):
365
- # 检查是否有 vnc.html
373
+ # 检查是否有 vnc.html(完整 noVNC 安装)
366
374
  for sub in ["", "/vnc_lite", "/vnc"]:
367
375
  html = os.path.join(path + sub, "vnc.html")
368
376
  vnc_lite = os.path.join(path + sub, "vnc_lite.html")
369
377
  if os.path.isfile(html) or os.path.isfile(vnc_lite):
370
378
  return path + sub if sub else path
379
+ # [v1.20.9] 检查是否有 lib/rfb.js(内置精简 noVNC)
380
+ rfb_js = os.path.join(path, "lib", "rfb.js")
381
+ if os.path.isfile(rfb_js):
382
+ return path
371
383
 
372
384
  return None
373
385
 
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+
3
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports["default"] = void 0;
8
+ var Log = _interopRequireWildcard(require("./util/logging.js"));
9
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
10
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
11
+ /* This Source Code Form is subject to the terms of the Mozilla Public
12
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
13
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
14
+ // From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js
15
+ var _default = exports["default"] = {
16
+ /* Convert data (an array of integers) to a Base64 string. */
17
+ toBase64Table: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
18
+ base64Pad: '=',
19
+ encode: function encode(data) {
20
+ "use strict";
21
+
22
+ var result = '';
23
+ var length = data.length;
24
+ var lengthpad = length % 3;
25
+ // Convert every three bytes to 4 ascii characters.
26
+
27
+ for (var i = 0; i < length - 2; i += 3) {
28
+ result += this.toBase64Table[data[i] >> 2];
29
+ result += this.toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
30
+ result += this.toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
31
+ result += this.toBase64Table[data[i + 2] & 0x3f];
32
+ }
33
+
34
+ // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
35
+ var j = length - lengthpad;
36
+ if (lengthpad === 2) {
37
+ result += this.toBase64Table[data[j] >> 2];
38
+ result += this.toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
39
+ result += this.toBase64Table[(data[j + 1] & 0x0f) << 2];
40
+ result += this.toBase64Table[64];
41
+ } else if (lengthpad === 1) {
42
+ result += this.toBase64Table[data[j] >> 2];
43
+ result += this.toBase64Table[(data[j] & 0x03) << 4];
44
+ result += this.toBase64Table[64];
45
+ result += this.toBase64Table[64];
46
+ }
47
+ return result;
48
+ },
49
+ /* Convert Base64 data to a string */
50
+ /* eslint-disable comma-spacing */
51
+ toBinaryTable: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1],
52
+ /* eslint-enable comma-spacing */decode: function decode(data) {
53
+ var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
54
+ var dataLength = data.indexOf('=') - offset;
55
+ if (dataLength < 0) {
56
+ dataLength = data.length - offset;
57
+ }
58
+
59
+ /* Every four characters is 3 resulting numbers */
60
+ var resultLength = (dataLength >> 2) * 3 + Math.floor(dataLength % 4 / 1.5);
61
+ var result = new Array(resultLength);
62
+
63
+ // Convert one by one.
64
+
65
+ var leftbits = 0; // number of bits decoded, but yet to be appended
66
+ var leftdata = 0; // bits decoded, but yet to be appended
67
+ for (var idx = 0, i = offset; i < data.length; i++) {
68
+ var c = this.toBinaryTable[data.charCodeAt(i) & 0x7f];
69
+ var padding = data.charAt(i) === this.base64Pad;
70
+ // Skip illegal characters and whitespace
71
+ if (c === -1) {
72
+ Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
73
+ continue;
74
+ }
75
+
76
+ // Collect data into leftdata, update bitcount
77
+ leftdata = leftdata << 6 | c;
78
+ leftbits += 6;
79
+
80
+ // If we have 8 or more bits, append 8 bits to the result
81
+ if (leftbits >= 8) {
82
+ leftbits -= 8;
83
+ // Append if not padding.
84
+ if (!padding) {
85
+ result[idx++] = leftdata >> leftbits & 0xff;
86
+ }
87
+ leftdata &= (1 << leftbits) - 1;
88
+ }
89
+ }
90
+
91
+ // If there are any bits left, the base64 string was corrupted
92
+ if (leftbits) {
93
+ var err = new Error('Corrupted base64 string');
94
+ err.name = 'Base64-Error';
95
+ throw err;
96
+ }
97
+ return result;
98
+ }
99
+ };
100
+ /* End of Base64 namespace */