myagent-ai 1.23.16 → 1.23.18
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/package.json +1 -1
- package/web/api_server.py +86 -110
package/package.json
CHANGED
package/web/api_server.py
CHANGED
|
@@ -1007,16 +1007,75 @@ class ApiServer:
|
|
|
1007
1007
|
</div>
|
|
1008
1008
|
</div>
|
|
1009
1009
|
|
|
1010
|
-
<!-- [v1.
|
|
1010
|
+
<!-- [v1.23.16] noVNC 组件加载:本地优先,CDN 回退 -->
|
|
1011
1011
|
<script>
|
|
1012
|
-
// [v1.
|
|
1013
|
-
// 本地 data/novnc/lib/ 中的文件是 CommonJS 格式,不能直接用 import()
|
|
1012
|
+
// [v1.23.16] 本地 noVNC 加载器 — 支持 ../ 相对路径解析
|
|
1014
1013
|
async function loadLocalNoVNC() {{
|
|
1015
1014
|
const basePath = '/vnc/lib/';
|
|
1016
|
-
|
|
1015
|
+
const _modules = {{}};
|
|
1016
|
+
|
|
1017
|
+
// 规范化路径:处理 ./ 和 ../ 相对路径
|
|
1018
|
+
function resolvePath(fromModId, depId) {{
|
|
1019
|
+
if (!depId.startsWith('.')) return depId;
|
|
1020
|
+
// 取 fromModId 所在目录
|
|
1021
|
+
const baseParts = fromModId.split('/');
|
|
1022
|
+
baseParts.pop(); // 去掉文件名,得到目录
|
|
1023
|
+
const depParts = depId.split('/');
|
|
1024
|
+
for (const part of depParts) {{
|
|
1025
|
+
if (part === '.') continue;
|
|
1026
|
+
else if (part === '..') baseParts.pop();
|
|
1027
|
+
else baseParts.push(part);
|
|
1028
|
+
}}
|
|
1029
|
+
return baseParts.join('/');
|
|
1030
|
+
}}
|
|
1031
|
+
|
|
1032
|
+
// 去掉 .js 后缀(模块 ID 不含后缀)
|
|
1033
|
+
function stripJs(p) {{ return p.endsWith('.js') ? p.slice(0, -3) : p; }}
|
|
1034
|
+
|
|
1035
|
+
// 加载并注册单个模块
|
|
1036
|
+
async function loadModule(filePath) {{
|
|
1037
|
+
const modId = stripJs(filePath);
|
|
1038
|
+
if (_modules[modId]) return _modules[modId]; // 已加载
|
|
1039
|
+
const resp = await fetch(basePath + filePath);
|
|
1040
|
+
if (!resp.ok) throw new Error('Failed to fetch ' + filePath + ': ' + resp.status);
|
|
1041
|
+
const code = await resp.text();
|
|
1042
|
+
const modExports = {{}};
|
|
1043
|
+
_modules[modId] = modExports;
|
|
1044
|
+
try {{
|
|
1045
|
+
const fn = new Function('exports', 'require', 'module', code);
|
|
1046
|
+
fn(modExports, function(depId) {{
|
|
1047
|
+
const resolved = stripJs(resolvePath(modId, depId));
|
|
1048
|
+
return _modules[resolved] || {{}};
|
|
1049
|
+
}}, {{ exports: modExports }});
|
|
1050
|
+
}} catch(e) {{
|
|
1051
|
+
console.warn('[noVNC] Module error:', filePath, e);
|
|
1052
|
+
}}
|
|
1053
|
+
return modExports;
|
|
1054
|
+
}}
|
|
1055
|
+
|
|
1056
|
+
// 按依赖顺序加载所有 noVNC 模块
|
|
1017
1057
|
const depFiles = [
|
|
1018
|
-
|
|
1019
|
-
'vendor/pako/lib/
|
|
1058
|
+
// pako vendor (zlib 依赖)
|
|
1059
|
+
'vendor/pako/lib/utils/common.js',
|
|
1060
|
+
'vendor/pako/lib/zlib/adler32.js',
|
|
1061
|
+
'vendor/pako/lib/zlib/crc32.js',
|
|
1062
|
+
'vendor/pako/lib/zlib/messages.js',
|
|
1063
|
+
'vendor/pako/lib/zlib/inffast.js',
|
|
1064
|
+
'vendor/pako/lib/zlib/inftrees.js',
|
|
1065
|
+
'vendor/pako/lib/zlib/trees.js',
|
|
1066
|
+
'vendor/pako/lib/zlib/inflate.js',
|
|
1067
|
+
'vendor/pako/lib/zlib/deflate.js',
|
|
1068
|
+
'vendor/pako/lib/zlib/gzheader.js',
|
|
1069
|
+
'vendor/pako/lib/zlib/zstream.js',
|
|
1070
|
+
// noVNC core
|
|
1071
|
+
'util/logging.js',
|
|
1072
|
+
'util/events.js',
|
|
1073
|
+
'util/eventtarget.js',
|
|
1074
|
+
'util/strings.js',
|
|
1075
|
+
'util/browser.js',
|
|
1076
|
+
'util/int.js',
|
|
1077
|
+
'util/element.js',
|
|
1078
|
+
'util/cursor.js',
|
|
1020
1079
|
'base64.js',
|
|
1021
1080
|
'websock.js',
|
|
1022
1081
|
'display.js',
|
|
@@ -1030,97 +1089,31 @@ async function loadLocalNoVNC() {{
|
|
|
1030
1089
|
'decoders/tightpng.js',
|
|
1031
1090
|
'decoders/zrle.js',
|
|
1032
1091
|
'decoders/jpeg.js',
|
|
1033
|
-
'
|
|
1034
|
-
'
|
|
1035
|
-
'util/logging.js',
|
|
1036
|
-
'util/strings.js',
|
|
1037
|
-
'util/browser.js',
|
|
1038
|
-
'util/int.js',
|
|
1039
|
-
'util/element.js',
|
|
1040
|
-
'util/cursor.js',
|
|
1092
|
+
'encodings.js',
|
|
1093
|
+
'input/keysymdef.js',
|
|
1041
1094
|
'input/keysym.js',
|
|
1042
1095
|
'input/xtscancodes.js',
|
|
1043
|
-
'input/util.js',
|
|
1044
|
-
'input/domkeytable.js',
|
|
1045
1096
|
'input/vkeys.js',
|
|
1097
|
+
'input/fixedkeys.js',
|
|
1098
|
+
'input/domkeytable.js',
|
|
1099
|
+
'input/util.js',
|
|
1046
1100
|
'input/keyboard.js',
|
|
1047
1101
|
'input/gesturehandler.js',
|
|
1048
|
-
|
|
1102
|
+
// crypto (rfb.js → ra2.js → crypto/)
|
|
1103
|
+
'crypto/bigint.js',
|
|
1104
|
+
'crypto/dh.js',
|
|
1105
|
+
'crypto/md5.js',
|
|
1106
|
+
'crypto/des.js',
|
|
1107
|
+
'crypto/aes.js',
|
|
1108
|
+
'crypto/rsa.js',
|
|
1109
|
+
'crypto/crypto.js',
|
|
1110
|
+
'ra2.js',
|
|
1049
1111
|
];
|
|
1050
|
-
// 加载所有依赖文件为全局变量
|
|
1051
1112
|
for (const file of depFiles) {{
|
|
1052
|
-
|
|
1053
|
-
if (!resp.ok) throw new Error('Failed to fetch ' + file + ': ' + resp.status);
|
|
1054
|
-
const code = await resp.text();
|
|
1055
|
-
// 使用 Function 构造器执行 CommonJS 代码,注入 require 和 exports
|
|
1056
|
-
const _modules = window.__novnc_modules = window.__novnc_modules || {{}};
|
|
1057
|
-
const modId = file.replace('.js', '');
|
|
1058
|
-
const modExports = {{}};
|
|
1059
|
-
_modules[modId] = modExports;
|
|
1060
|
-
try {{
|
|
1061
|
-
const fn = new Function('exports', 'require', 'module', code);
|
|
1062
|
-
fn(modExports, function(depId) {{
|
|
1063
|
-
// 解析相对路径
|
|
1064
|
-
let resolved = depId;
|
|
1065
|
-
if (depId.startsWith('./')) {{
|
|
1066
|
-
resolved = (modId.substring(0, modId.lastIndexOf('/') + 1) || '') + depId.substring(2);
|
|
1067
|
-
}}
|
|
1068
|
-
return _modules[resolved] || {{}};
|
|
1069
|
-
}}, {{ exports: modExports }});
|
|
1070
|
-
}} catch(e) {{
|
|
1071
|
-
console.warn('[noVNC] Failed to load module:', file, e);
|
|
1072
|
-
}}
|
|
1113
|
+
await loadModule(file);
|
|
1073
1114
|
}}
|
|
1074
1115
|
// 最后加载 rfb.js
|
|
1075
|
-
const
|
|
1076
|
-
if (!resp.ok) throw new Error('Failed to fetch rfb.js: ' + resp.status);
|
|
1077
|
-
const code = await resp.text();
|
|
1078
|
-
const _modules = window.__novnc_modules || {{}};
|
|
1079
|
-
const rfbExports = {{}};
|
|
1080
|
-
_modules['rfb'] = rfbExports;
|
|
1081
|
-
const fn = new Function('exports', 'require', 'module', code);
|
|
1082
|
-
fn(rfbExports, function(depId) {{
|
|
1083
|
-
let resolved = depId;
|
|
1084
|
-
if (depId.startsWith('./')) {{
|
|
1085
|
-
resolved = 'rfb/' + depId.substring(2);
|
|
1086
|
-
// 映射到实际模块路径
|
|
1087
|
-
const pathMap = {{
|
|
1088
|
-
'./util/int': 'util/int',
|
|
1089
|
-
'./util/logging': 'util/logging',
|
|
1090
|
-
'./util/strings': 'util/strings',
|
|
1091
|
-
'./util/browser': 'util/browser',
|
|
1092
|
-
'./util/element': 'util/element',
|
|
1093
|
-
'./util/events': 'util/events',
|
|
1094
|
-
'./util/eventtarget': 'util/eventtarget',
|
|
1095
|
-
'./display': 'display',
|
|
1096
|
-
'./inflator': 'inflator',
|
|
1097
|
-
'./deflator': 'deflator',
|
|
1098
|
-
'./websock': 'websock',
|
|
1099
|
-
'./decoders/copyrect': 'decoders/copyrect',
|
|
1100
|
-
'./decoders/raw': 'decoders/raw',
|
|
1101
|
-
'./decoders/rre': 'decoders/rre',
|
|
1102
|
-
'./decoders/hextile': 'decoders/hextile',
|
|
1103
|
-
'./decoders/tight': 'decoders/tight',
|
|
1104
|
-
'./decoders/tightpng': 'decoders/tightpng',
|
|
1105
|
-
'./decoders/zrle': 'decoders/zrle',
|
|
1106
|
-
'./decoders/jpeg': 'decoders/jpeg',
|
|
1107
|
-
'./encodings': 'encodings',
|
|
1108
|
-
'./input/keysym': 'input/keysym',
|
|
1109
|
-
'./input/keyboard': 'input/keyboard',
|
|
1110
|
-
'./input/xtscancodes': 'input/xtscancodes',
|
|
1111
|
-
'./input/util': 'input/util',
|
|
1112
|
-
'./input/domkeytable': 'input/domkeytable',
|
|
1113
|
-
'./input/vkeys': 'input/vkeys',
|
|
1114
|
-
'./input/gesturehandler': 'input/gesturehandler',
|
|
1115
|
-
'./base64': 'base64',
|
|
1116
|
-
}};
|
|
1117
|
-
if (depId.startsWith('./')) {{
|
|
1118
|
-
const mapped = pathMap[depId];
|
|
1119
|
-
if (mapped) resolved = mapped;
|
|
1120
|
-
}}
|
|
1121
|
-
}}
|
|
1122
|
-
return _modules[resolved] || {{}};
|
|
1123
|
-
}}, {{ exports: rfbExports }});
|
|
1116
|
+
const rfbExports = await loadModule('rfb.js');
|
|
1124
1117
|
return rfbExports.default || rfbExports;
|
|
1125
1118
|
}}
|
|
1126
1119
|
</script>
|
|
@@ -1129,34 +1122,16 @@ try {{
|
|
|
1129
1122
|
let RFB = null;
|
|
1130
1123
|
let loadError = '';
|
|
1131
1124
|
|
|
1132
|
-
// [v1.
|
|
1125
|
+
// [v1.23.16] 从本地服务器加载 noVNC(data/novnc/lib/)
|
|
1133
1126
|
try {{
|
|
1134
1127
|
RFB = await loadLocalNoVNC();
|
|
1135
1128
|
}} catch (localErr) {{
|
|
1136
1129
|
loadError = localErr.message;
|
|
1137
|
-
console.
|
|
1138
|
-
// 本地加载失败,尝试 CDN 回退(多源容错)
|
|
1139
|
-
const CDN_SOURCES = [
|
|
1140
|
-
'https://cdn.jsdelivr.net/npm/@novnc/novnc@1.5.0/core/rfb.js',
|
|
1141
|
-
'https://fastly.jsdelivr.net/npm/@novnc/novnc@1.5.0/core/rfb.js',
|
|
1142
|
-
'https://unpkg.com/@novnc/novnc@1.5.0/core/rfb.js',
|
|
1143
|
-
'https://registry.npmmirror.com/@novnc/novnc/1.5.0/files/core/rfb.js',
|
|
1144
|
-
'https://cdn.staticfile.net/novnc/novnc/1.5.0/files/core/rfb.js',
|
|
1145
|
-
];
|
|
1146
|
-
for (const src of CDN_SOURCES) {{
|
|
1147
|
-
try {{
|
|
1148
|
-
const mod = await import(src);
|
|
1149
|
-
RFB = mod.default || mod.RFB;
|
|
1150
|
-
if (RFB) break;
|
|
1151
|
-
}} catch (e) {{
|
|
1152
|
-
loadError = e.message;
|
|
1153
|
-
continue;
|
|
1154
|
-
}}
|
|
1155
|
-
}}
|
|
1130
|
+
console.error('[VNC] 本地 noVNC 加载失败:', localErr);
|
|
1156
1131
|
}}
|
|
1157
1132
|
|
|
1158
1133
|
if (!RFB) {{
|
|
1159
|
-
throw new Error('noVNC
|
|
1134
|
+
throw new Error('noVNC 本地加载失败: ' + loadError);
|
|
1160
1135
|
}}
|
|
1161
1136
|
|
|
1162
1137
|
initVNC(RFB);
|
|
@@ -1166,7 +1141,8 @@ try {{
|
|
|
1166
1141
|
document.getElementById('statusTitle').textContent = 'VNC 组件加载失败';
|
|
1167
1142
|
document.getElementById('statusMsg').innerHTML =
|
|
1168
1143
|
'noVNC 组件加载失败: ' + e.message + '<br><br>' +
|
|
1169
|
-
'请确保 myagent/data/novnc/lib/
|
|
1144
|
+
'请确保 myagent/data/novnc/lib/ 目录存在。<br>' +
|
|
1145
|
+
'在服务器上运行: myagent-ai reinstall';
|
|
1170
1146
|
document.getElementById('statusActions').style.display = '';
|
|
1171
1147
|
console.error('[VNC] 组件加载失败:', e);
|
|
1172
1148
|
}}
|