myagent-ai 1.20.8 → 1.20.10
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/config.py +1 -0
- package/core/context_builder.py +17 -0
- package/core/deps_checker.py +11 -0
- package/core/vnc_manager.py +18 -6
- package/core/web_control.py +19 -1
- 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 +53 -1
- package/package.json +1 -1
- package/skills/agent_tool_skill.py +113 -0
- package/skills/file_send.py +44 -2
- package/web/api_server.py +278 -108
- package/web/ui/chat/chat_main.js +27 -14
package/config.py
CHANGED
|
@@ -155,6 +155,7 @@ class AppConfig:
|
|
|
155
155
|
data_dir: str = "" # 数据目录,默认 ~/.myagent/
|
|
156
156
|
language: str = "zh-CN"
|
|
157
157
|
timezone: str = "Asia/Shanghai" # 时区,用于生成时间戳和提示词中的当前时间
|
|
158
|
+
public_url: str = "" # [v1.20.8] 公开访问 URL(用于生成文件下载链接),如 http://your-server.com:8767
|
|
158
159
|
|
|
159
160
|
|
|
160
161
|
# ==============================================================================
|
package/core/context_builder.py
CHANGED
|
@@ -238,12 +238,29 @@ class ContextBuilder:
|
|
|
238
238
|
f"描述: {safe_desc}",
|
|
239
239
|
]
|
|
240
240
|
|
|
241
|
+
# [v1.20.8] 注入工作目录信息,让 Agent 知道文件应保存到哪里
|
|
242
|
+
work_dir = self._get_workspace_dir()
|
|
243
|
+
if work_dir:
|
|
244
|
+
parts.append(f"工作目录: {_xml_escape(str(work_dir))}")
|
|
245
|
+
parts.append(f"文件保存说明: 通过 file_write 或代码生成的文件请保存到工作目录下的 userfiles 子目录。发送文件给用户请使用 file_send 工具。")
|
|
246
|
+
|
|
241
247
|
if agent_override_prompt:
|
|
242
248
|
parts.append(f"附加指令: {_xml_escape(agent_override_prompt)}")
|
|
243
249
|
|
|
244
250
|
parts.append("</whomi>")
|
|
245
251
|
return "\n".join(parts)
|
|
246
252
|
|
|
253
|
+
def _get_workspace_dir(self) -> Optional[str]:
|
|
254
|
+
"""[v1.20.8] 获取工作目录路径(~/.myagent/data/workspace)"""
|
|
255
|
+
try:
|
|
256
|
+
from config import ConfigManager
|
|
257
|
+
cm = ConfigManager()
|
|
258
|
+
wd = cm.data_dir / "workspace"
|
|
259
|
+
wd.mkdir(parents=True, exist_ok=True)
|
|
260
|
+
return str(wd)
|
|
261
|
+
except Exception:
|
|
262
|
+
return None
|
|
263
|
+
|
|
247
264
|
def _build_memory(self, query: str, session_id: str, recall: str = "", memory_context_prompt: str = "") -> str:
|
|
248
265
|
"""
|
|
249
266
|
构建 <automemory> 和 <recall_memory> 段落 —— 双层记忆检索结果。
|
package/core/deps_checker.py
CHANGED
|
@@ -126,6 +126,17 @@ DEPENDENCIES: List[DepInfo] = [
|
|
|
126
126
|
# ── 远程桌面 (VNC) [v1.17.0] ──
|
|
127
127
|
# VNC 依赖通过 apt 安装 (xvfb, x11vnc),websockify 通过 pip 安装
|
|
128
128
|
# 实际检测和安装在 VNCManager.ensure_dependencies() 中完成
|
|
129
|
+
|
|
130
|
+
# ── 系统工具 [v1.20.9] ──
|
|
131
|
+
# ffmpeg: SenseVoice 音频解码必需 (WAV→16kHz转换)
|
|
132
|
+
]
|
|
133
|
+
|
|
134
|
+
# [v1.20.9] 系统级工具依赖列表(非 Python 包,需通过系统包管理器安装)
|
|
135
|
+
SYSTEM_TOOLS = [
|
|
136
|
+
{"name": "ffmpeg", "note": "FFmpeg 多媒体处理工具 (SenseVoice STT 必需, 用于音频格式转换)",
|
|
137
|
+
"install": {"linux": "sudo apt install ffmpeg", "macos": "brew install ffmpeg"}},
|
|
138
|
+
{"name": "convert", "note": "ImageMagick 图像处理工具 (VNC 截图备用)",
|
|
139
|
+
"install": {"linux": "sudo apt install imagemagick", "macos": "brew install imagemagick"}},
|
|
129
140
|
]
|
|
130
141
|
|
|
131
142
|
|
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
|
|
package/core/web_control.py
CHANGED
|
@@ -415,12 +415,30 @@ class WebControlManager:
|
|
|
415
415
|
"""
|
|
416
416
|
向客户端下发命令并等待结果。
|
|
417
417
|
Agent 工具调用线程阻塞在此, 直到客户端返回结果或超时。
|
|
418
|
+
|
|
419
|
+
[v1.20.9] 修复: 如果面板尚未打开(刚执行了 open 但客户端还没加载完成),
|
|
420
|
+
会等待最多 15 秒让面板打开,而不是立即报错。
|
|
418
421
|
"""
|
|
419
422
|
session = self.get_session(session_id)
|
|
420
423
|
if not session:
|
|
421
424
|
return {"success": False, "error": f"Session {session_id} not found or expired"}
|
|
425
|
+
|
|
426
|
+
# [v1.20.9] 等待面板打开(最多 15 秒)
|
|
422
427
|
if not session.is_panel_open:
|
|
423
|
-
|
|
428
|
+
logger.info(f"[WebControl] 等待面板打开 (session: {session_id}, action: {action})")
|
|
429
|
+
waited = 0
|
|
430
|
+
while waited < 15:
|
|
431
|
+
await asyncio.sleep(1)
|
|
432
|
+
waited += 1
|
|
433
|
+
if session.is_panel_open:
|
|
434
|
+
logger.info(f"[WebControl] 面板已打开 (等待了 {waited}s)")
|
|
435
|
+
break
|
|
436
|
+
# 检查会话是否已关闭
|
|
437
|
+
if session._closed:
|
|
438
|
+
return {"success": False, "error": "Session closed while waiting for panel"}
|
|
439
|
+
|
|
440
|
+
if not session.is_panel_open:
|
|
441
|
+
return {"success": False, "error": "Panel is not open. Use 'open' action first. (waited 15s)"}
|
|
424
442
|
|
|
425
443
|
cmd_id = uuid.uuid4().hex[:10]
|
|
426
444
|
command = {
|
|
@@ -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 */
|