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.
- package/agents/main_agent.py +37 -2
- package/core/vnc_manager.py +18 -6
- package/data/novnc/lib/base64.js +100 -0
- package/data/novnc/lib/crypto/aes.js +481 -0
- package/data/novnc/lib/crypto/bigint.js +41 -0
- package/data/novnc/lib/crypto/crypto.js +109 -0
- package/data/novnc/lib/crypto/des.js +374 -0
- package/data/novnc/lib/crypto/dh.js +81 -0
- package/data/novnc/lib/crypto/md5.js +97 -0
- package/data/novnc/lib/crypto/rsa.js +312 -0
- package/data/novnc/lib/decoders/copyrect.js +40 -0
- package/data/novnc/lib/decoders/hextile.js +195 -0
- package/data/novnc/lib/decoders/jpeg.js +175 -0
- package/data/novnc/lib/decoders/raw.js +66 -0
- package/data/novnc/lib/decoders/rre.js +52 -0
- package/data/novnc/lib/decoders/tight.js +363 -0
- package/data/novnc/lib/decoders/tightpng.js +51 -0
- package/data/novnc/lib/decoders/zrle.js +192 -0
- package/data/novnc/lib/deflator.js +88 -0
- package/data/novnc/lib/display.js +527 -0
- package/data/novnc/lib/encodings.js +63 -0
- package/data/novnc/lib/inflator.js +77 -0
- package/data/novnc/lib/input/domkeytable.js +313 -0
- package/data/novnc/lib/input/fixedkeys.js +127 -0
- package/data/novnc/lib/input/gesturehandler.js +573 -0
- package/data/novnc/lib/input/keyboard.js +292 -0
- package/data/novnc/lib/input/keysym.js +878 -0
- package/data/novnc/lib/input/keysymdef.js +1351 -0
- package/data/novnc/lib/input/util.js +217 -0
- package/data/novnc/lib/input/vkeys.js +121 -0
- package/data/novnc/lib/input/xtscancodes.js +343 -0
- package/data/novnc/lib/ra2.js +535 -0
- package/data/novnc/lib/rfb.js +3225 -0
- package/data/novnc/lib/util/browser.js +147 -0
- package/data/novnc/lib/util/cursor.js +269 -0
- package/data/novnc/lib/util/element.js +41 -0
- package/data/novnc/lib/util/events.js +133 -0
- package/data/novnc/lib/util/eventtarget.js +53 -0
- package/data/novnc/lib/util/int.js +21 -0
- package/data/novnc/lib/util/logging.js +56 -0
- package/data/novnc/lib/util/strings.js +36 -0
- package/data/novnc/lib/vendor/pako/lib/utils/common.js +55 -0
- package/data/novnc/lib/vendor/pako/lib/zlib/adler32.js +29 -0
- package/data/novnc/lib/vendor/pako/lib/zlib/constants.js +47 -0
- package/data/novnc/lib/vendor/pako/lib/zlib/crc32.js +35 -0
- package/data/novnc/lib/vendor/pako/lib/zlib/deflate.js +1721 -0
- package/data/novnc/lib/vendor/pako/lib/zlib/gzheader.js +41 -0
- package/data/novnc/lib/vendor/pako/lib/zlib/inffast.js +327 -0
- package/data/novnc/lib/vendor/pako/lib/zlib/inflate.js +1602 -0
- package/data/novnc/lib/vendor/pako/lib/zlib/inftrees.js +310 -0
- package/data/novnc/lib/vendor/pako/lib/zlib/messages.js +25 -0
- package/data/novnc/lib/vendor/pako/lib/zlib/trees.js +1150 -0
- package/data/novnc/lib/vendor/pako/lib/zlib/zstream.js +30 -0
- package/data/novnc/lib/websock.js +395 -0
- package/main.py +6 -0
- package/package.json +1 -1
- package/skills/agent_tool_skill.py +113 -0
- package/web/api_server.py +27 -40
- package/web/ui/chat/chat_main.js +15 -2
package/agents/main_agent.py
CHANGED
|
@@ -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
|
-
|
|
1694
|
-
|
|
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
|
package/core/vnc_manager.py
CHANGED
|
@@ -335,15 +335,23 @@ class VNCManager:
|
|
|
335
335
|
"""查找 noVNC web 文件目录
|
|
336
336
|
|
|
337
337
|
搜索顺序:
|
|
338
|
-
1. /
|
|
339
|
-
2. /usr/
|
|
340
|
-
3.
|
|
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 */
|