myagent-ai 1.23.19 → 1.23.21

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 (79) hide show
  1. package/chatbot/whatsapp_bot.py +0 -0
  2. package/chatbot/whatsapp_bridge/bridge.mjs +0 -0
  3. package/chatbot/whatsapp_bridge/package.json +0 -0
  4. package/core/stt.py +0 -0
  5. package/core/tool_dispatcher.py +0 -0
  6. package/core/web_control.py +0 -0
  7. package/data/novnc/lib/base64.js +0 -0
  8. package/data/novnc/lib/crypto/aes.js +0 -0
  9. package/data/novnc/lib/crypto/bigint.js +0 -0
  10. package/data/novnc/lib/crypto/crypto.js +0 -0
  11. package/data/novnc/lib/crypto/des.js +0 -0
  12. package/data/novnc/lib/crypto/dh.js +0 -0
  13. package/data/novnc/lib/crypto/md5.js +0 -0
  14. package/data/novnc/lib/crypto/rsa.js +0 -0
  15. package/data/novnc/lib/decoders/copyrect.js +0 -0
  16. package/data/novnc/lib/decoders/hextile.js +0 -0
  17. package/data/novnc/lib/decoders/jpeg.js +0 -0
  18. package/data/novnc/lib/decoders/raw.js +0 -0
  19. package/data/novnc/lib/decoders/rre.js +0 -0
  20. package/data/novnc/lib/decoders/tight.js +0 -0
  21. package/data/novnc/lib/decoders/tightpng.js +0 -0
  22. package/data/novnc/lib/decoders/zrle.js +0 -0
  23. package/data/novnc/lib/deflator.js +0 -0
  24. package/data/novnc/lib/display.js +0 -0
  25. package/data/novnc/lib/encodings.js +0 -0
  26. package/data/novnc/lib/inflator.js +0 -0
  27. package/data/novnc/lib/input/domkeytable.js +0 -0
  28. package/data/novnc/lib/input/fixedkeys.js +0 -0
  29. package/data/novnc/lib/input/gesturehandler.js +0 -0
  30. package/data/novnc/lib/input/keyboard.js +0 -0
  31. package/data/novnc/lib/input/keysym.js +0 -0
  32. package/data/novnc/lib/input/keysymdef.js +0 -0
  33. package/data/novnc/lib/input/util.js +0 -0
  34. package/data/novnc/lib/input/vkeys.js +0 -0
  35. package/data/novnc/lib/input/xtscancodes.js +0 -0
  36. package/data/novnc/lib/ra2.js +0 -0
  37. package/data/novnc/lib/rfb.js +0 -0
  38. package/data/novnc/lib/util/browser.js +0 -0
  39. package/data/novnc/lib/util/cursor.js +0 -0
  40. package/data/novnc/lib/util/element.js +0 -0
  41. package/data/novnc/lib/util/events.js +0 -0
  42. package/data/novnc/lib/util/eventtarget.js +0 -0
  43. package/data/novnc/lib/util/int.js +0 -0
  44. package/data/novnc/lib/util/logging.js +0 -0
  45. package/data/novnc/lib/util/strings.js +0 -0
  46. package/data/novnc/lib/vendor/pako/lib/utils/common.js +0 -0
  47. package/data/novnc/lib/vendor/pako/lib/zlib/adler32.js +0 -0
  48. package/data/novnc/lib/vendor/pako/lib/zlib/constants.js +0 -0
  49. package/data/novnc/lib/vendor/pako/lib/zlib/crc32.js +0 -0
  50. package/data/novnc/lib/vendor/pako/lib/zlib/deflate.js +0 -0
  51. package/data/novnc/lib/vendor/pako/lib/zlib/gzheader.js +0 -0
  52. package/data/novnc/lib/vendor/pako/lib/zlib/inffast.js +0 -0
  53. package/data/novnc/lib/vendor/pako/lib/zlib/inflate.js +0 -0
  54. package/data/novnc/lib/vendor/pako/lib/zlib/inftrees.js +0 -0
  55. package/data/novnc/lib/vendor/pako/lib/zlib/messages.js +0 -0
  56. package/data/novnc/lib/vendor/pako/lib/zlib/trees.js +0 -0
  57. package/data/novnc/lib/vendor/pako/lib/zlib/zstream.js +0 -0
  58. package/data/novnc/lib/websock.js +0 -0
  59. package/package.json +1 -1
  60. package/scripts/cli.py +0 -0
  61. package/skills/agent_tool_skill.py +0 -0
  62. package/web/ui/admin/admin-agents.js +570 -0
  63. package/web/ui/admin/admin-core.js +322 -0
  64. package/web/ui/admin/admin-dashboard.js +153 -0
  65. package/web/ui/admin/admin-executor.js +67 -0
  66. package/web/ui/admin/admin-files.js +81 -0
  67. package/web/ui/admin/admin-llm.js +190 -0
  68. package/web/ui/admin/admin-logs.js +69 -0
  69. package/web/ui/admin/admin-memory.js +91 -0
  70. package/web/ui/admin/admin-org.js +283 -0
  71. package/web/ui/admin/admin-permissions.js +147 -0
  72. package/web/ui/admin/admin-platforms.js +221 -0
  73. package/web/ui/admin/admin-sessions.js +182 -0
  74. package/web/ui/admin/admin-skills.js +217 -0
  75. package/web/ui/admin/admin-system.js +154 -0
  76. package/web/ui/admin/admin-tasks.js +131 -0
  77. package/web/ui/chat/chat_main.js +292 -304
  78. package/web/ui/chat/flow_engine.js +96 -41
  79. package/web/ui/index.html +15 -2776
@@ -607,51 +607,72 @@ function updateStreamingMessage(msgIdx) {
607
607
  }
608
608
 
609
609
  // ── [v1.23.15] 增量渲染文件卡片(v2_file 事件到达时立即显示) ──
610
+ // [v1.23.20] DOM 结构完全对齐 buildMessageHtml:
611
+ // 图片/音视频 → .msg-attachments.msg-attachments-images(在 bubble 之前)
612
+ // 非媒体文件 → .msg-attachments.msg-attachments-files(在 bubble 之后)
610
613
  if (msg._files && msg._files.length > 0) {
611
- var existingFiles = bubbleWrapper ? bubbleWrapper.querySelectorAll(':scope > .msg-attachments') : contentArea.querySelectorAll(':scope > .msg-attachments');
614
+ // ── 图片/音视频容器(和 buildMessageHtml imageAttachmentHtml 一致) ──
615
+ var imageContainer = contentArea.querySelector(':scope > .msg-attachments-images');
616
+ // ── 非媒体文件容器(和 buildMessageHtml 的 fileAttachmentHtml 一致) ──
617
+ var existingFiles = contentArea.querySelectorAll(':scope > .msg-attachments-files');
612
618
  var fileContainer = existingFiles.length > 0 ? existingFiles[0] : null;
613
- if (!fileContainer) {
614
- fileContainer = document.createElement('div');
615
- fileContainer.className = 'msg-attachments msg-attachments-files';
616
- if (bubbleWrapper) {
617
- bubbleWrapper.appendChild(fileContainer);
618
- } else {
619
- contentArea.appendChild(fileContainer);
620
- }
621
- }
619
+
622
620
  // 只添加未渲染的新文件
623
- var renderedIds = fileContainer._renderedFileIds || [];
621
+ var renderedIds = (fileContainer ? fileContainer._renderedFileIds : []) || [];
622
+ var renderedImageIds = (imageContainer ? imageContainer._renderedImageIds : []) || [];
624
623
  for (var _fIdx = 0; _fIdx < msg._files.length; _fIdx++) {
625
624
  var _f = msg._files[_fIdx];
626
625
  var _fId = _f.id || _f.file_id || '';
627
- if (renderedIds.indexOf(_fId) >= 0) continue;
626
+ // 同时检查两个容器的已渲染列表
627
+ if (renderedIds.indexOf(_fId) >= 0 || renderedImageIds.indexOf(_fId) >= 0) continue;
628
628
  var _isImg = _f.type && _f.type.indexOf('image/') === 0;
629
629
  var _isAud = _f.type && _f.type.indexOf('audio/') === 0;
630
630
  var _isVid = _f.type && _f.type.indexOf('video/') === 0;
631
- // [v1.23.19] 图片/音频/视频也直接渲染(不再跳过等 renderMessages)
632
- if (_isImg && _fId) {
633
- var _imgDiv = document.createElement('div');
634
- _imgDiv.className = 'msg-image-wrapper agent-image';
635
- _imgDiv.innerHTML = '<img src="/api/file/' + _fId + '" class="msg-image" loading="lazy" alt="' + escapeHtml(_f.name || 'image') + '" onerror="this.onerror=null;this.style.background=\'var(--bg3)\';this.style.minHeight=\'60px\';this.alt=\'[图片加载失败]\'" onclick="openFileViewer(\'' + _fId + '\', this.src, \'' + escapeHtml(_f.name) + '\')" />';
636
- fileContainer.appendChild(_imgDiv);
637
- renderedIds.push(_fId);
638
- continue;
639
- }
640
- if (_isAud && _fId) {
641
- var _audDiv = document.createElement('div');
642
- _audDiv.className = 'msg-media-player';
643
- _audDiv.innerHTML = '<audio controls src="/api/file/' + _fId + '" style="width:100%;max-width:480px" preload="metadata" onplay="if(typeof muteTTS===\'function\')muteTTS()" onended="if(typeof unmuteTTS===\'function\')unmuteTTS()"></audio><div class="msg-media-title">' + escapeHtml(_f.name || '音频') + '</div>';
644
- fileContainer.appendChild(_audDiv);
645
- renderedIds.push(_fId);
631
+
632
+ if (_isImg || _isAud || _isVid) {
633
+ // 图片/音频/视频 imageContainer(和 buildMessageHtml 的 imageAttachmentHtml 一致)
634
+ if (!imageContainer) {
635
+ imageContainer = document.createElement('div');
636
+ imageContainer.className = 'msg-attachments msg-attachments-images';
637
+ imageContainer._renderedImageIds = [];
638
+ // 插入到 bubbleWrapper 之前(和 buildMessageHtml 顺序一致:images 先,media 后,bubble 后)
639
+ if (bubbleWrapper && bubbleWrapper.parentNode) {
640
+ bubbleWrapper.parentNode.insertBefore(imageContainer, bubbleWrapper);
641
+ } else {
642
+ contentArea.appendChild(imageContainer);
643
+ }
644
+ }
645
+ if (_isImg && _fId) {
646
+ var _imgDiv = document.createElement('div');
647
+ _imgDiv.className = 'msg-image-wrapper agent-image';
648
+ _imgDiv.innerHTML = '<img src="/api/file/' + _fId + '" class="msg-image" loading="lazy" alt="' + escapeHtml(_f.name || 'image') + '" onerror="this.onerror=null;this.style.background=\'var(--bg3)\';this.style.minHeight=\'60px\';this.alt=\'[图片加载失败]\'" onclick="openFileViewer(\'' + _fId + '\', this.src, \'' + escapeHtml(_f.name) + '\')" />';
649
+ imageContainer.appendChild(_imgDiv);
650
+ } else if (_isAud && _fId) {
651
+ var _audDiv = document.createElement('div');
652
+ _audDiv.className = 'msg-media-player';
653
+ _audDiv.innerHTML = '<audio controls src="/api/file/' + _fId + '" style="width:100%;max-width:480px" preload="metadata" onplay="if(typeof muteTTS===\'function\')muteTTS()" onended="if(typeof unmuteTTS===\'function\')unmuteTTS()"></audio><div class="msg-media-title">' + escapeHtml(_f.name || '音频') + '</div>';
654
+ imageContainer.appendChild(_audDiv);
655
+ } else if (_isVid && _fId) {
656
+ var _vidDiv = document.createElement('div');
657
+ _vidDiv.className = 'msg-media-player';
658
+ _vidDiv.innerHTML = '<video controls src="/api/file/' + _fId + '" style="width:100%;max-width:640px;border-radius:8px" preload="metadata" onplay="if(typeof muteTTS===\'function\')muteTTS()" onended="if(typeof unmuteTTS===\'function\')unmuteTTS()"></video><div class="msg-media-title">' + escapeHtml(_f.name || '视频') + '</div>';
659
+ imageContainer.appendChild(_vidDiv);
660
+ }
661
+ imageContainer._renderedImageIds.push(_fId);
646
662
  continue;
647
663
  }
648
- if (_isVid && _fId) {
649
- var _vidDiv = document.createElement('div');
650
- _vidDiv.className = 'msg-media-player';
651
- _vidDiv.innerHTML = '<video controls src="/api/file/' + _fId + '" style="width:100%;max-width:640px;border-radius:8px" preload="metadata" onplay="if(typeof muteTTS===\'function\')muteTTS()" onended="if(typeof unmuteTTS===\'function\')unmuteTTS()"></video><div class="msg-media-title">' + escapeHtml(_f.name || '视频') + '</div>';
652
- fileContainer.appendChild(_vidDiv);
653
- renderedIds.push(_fId);
654
- continue;
664
+
665
+ // 非媒体文件 fileContainer
666
+ if (!fileContainer) {
667
+ fileContainer = document.createElement('div');
668
+ fileContainer.className = 'msg-attachments msg-attachments-files';
669
+ fileContainer._renderedFileIds = [];
670
+ // 插入到 bubbleWrapper 之后(和 buildMessageHtml 顺序一致)
671
+ if (bubbleWrapper && bubbleWrapper.parentNode) {
672
+ bubbleWrapper.parentNode.insertBefore(fileContainer, bubbleWrapper.nextSibling);
673
+ } else {
674
+ contentArea.appendChild(fileContainer);
675
+ }
655
676
  }
656
677
  var _icon = _getFileIcon(_f.name || _f.type || '');
657
678
  var _sizeStr = _f.size ? formatFileSize(_f.size) : '';
@@ -666,20 +687,21 @@ function updateStreamingMessage(msgIdx) {
666
687
  '<a class="msg-file-download" href="/api/file/' + (_fId || '') + '?name=' + encodeURIComponent(_f.name || 'file') + '" download="' + escapeHtml(_f.name) + '" title="下载" onclick="event.stopPropagation()">⬇</a>' +
667
688
  '</span>';
668
689
  fileContainer.appendChild(_fDiv);
669
- renderedIds.push(_fId);
690
+ fileContainer._renderedFileIds.push(_fId);
670
691
  }
671
- fileContainer._renderedFileIds = renderedIds;
672
692
  }
673
693
 
674
694
  // ── [v1.23.19] 增量渲染在线媒体嵌入播放器(v2_media 事件) ──
695
+ // [v1.23.20] 媒体容器放在 bubbleWrapper 外部(和 buildMessageHtml 结构一致)
675
696
  if (msg._media && msg._media.length > 0) {
676
- var existingMedia = bubbleWrapper ? bubbleWrapper.querySelectorAll(':scope > .msg-attachments-media') : contentArea.querySelectorAll(':scope > .msg-attachments-media');
697
+ var existingMedia = contentArea.querySelectorAll(':scope > .msg-attachments-media');
677
698
  var mediaContainer = existingMedia.length > 0 ? existingMedia[0] : null;
678
699
  if (!mediaContainer) {
679
700
  mediaContainer = document.createElement('div');
680
701
  mediaContainer.className = 'msg-attachments msg-attachments-media';
681
- if (bubbleWrapper) {
682
- bubbleWrapper.appendChild(mediaContainer);
702
+ // 插入到 bubbleWrapper 之前(和 buildMessageHtml 顺序一致:media 先,bubble 后)
703
+ if (bubbleWrapper && bubbleWrapper.parentNode) {
704
+ bubbleWrapper.parentNode.insertBefore(mediaContainer, bubbleWrapper);
683
705
  } else {
684
706
  contentArea.appendChild(mediaContainer);
685
707
  }
@@ -2116,8 +2138,41 @@ async function sendMessage(opts) {
2116
2138
  // Assemble final content: prefer V2 reasoning/ask text over raw XML
2117
2139
  state.messages[msgIdx].content = _assembleV2Content(state.messages[msgIdx], msgParts);
2118
2140
  }
2119
- // Final render with completion flash animation
2120
- renderMessages();
2141
+ // ── [v1.23.20] 用统一渲染函数重建最后一条消息 DOM(和历史渲染完全一致) ──
2142
+ // 不再调 renderMessages() 全量重建(会丢失流式增量渲染的文件卡片等)
2143
+ var agent = findAgentByPath(state.activeAgent);
2144
+ var lastMsgRow = document.querySelector('#messagesInner .message-row:last-child');
2145
+ if (lastMsgRow && agent && state.messages[msgIdx]) {
2146
+ var newHtml = buildMessageHtml(state.messages[msgIdx], msgIdx, agent);
2147
+ if (newHtml) {
2148
+ // buildMessageHtml 可能返回 reasoningHtml + message-row(两个顶层元素)
2149
+ var wrapper = document.createElement('div');
2150
+ wrapper.innerHTML = newHtml;
2151
+ var children = Array.from(wrapper.children);
2152
+ // 移除旧的 reasoning block(container 直接子元素,在 message-row 之前)
2153
+ var prevSibling = lastMsgRow.previousElementSibling;
2154
+ if (prevSibling && prevSibling.classList && prevSibling.classList.contains('thought-block')) {
2155
+ var label = prevSibling.querySelector('.thought-label');
2156
+ if (label && label.textContent.includes('模型推理过程')) {
2157
+ prevSibling.remove();
2158
+ }
2159
+ }
2160
+ // 替换 message-row
2161
+ if (children.length >= 2) {
2162
+ // 有 reasoning block + message-row
2163
+ lastMsgRow.replaceWith(children[children.length - 1]);
2164
+ // reasoning block 插入到 message-row 之前
2165
+ for (var ci = 0; ci < children.length - 1; ci++) {
2166
+ lastMsgRow.parentNode.insertBefore(children[ci], lastMsgRow);
2167
+ }
2168
+ } else if (children.length === 1) {
2169
+ lastMsgRow.replaceWith(children[0]);
2170
+ }
2171
+ }
2172
+ } else {
2173
+ // Fallback: full re-render (should not normally happen)
2174
+ renderMessages();
2175
+ }
2121
2176
  // Auto-collapse thought blocks after streaming completes (smooth UX)
2122
2177
  setTimeout(function() {
2123
2178
  const thoughtBlocks = document.querySelectorAll('.thought-block:not(.streaming)');