myagent-ai 1.23.15 → 1.23.16

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myagent-ai",
3
- "version": "1.23.15",
3
+ "version": "1.23.16",
4
4
  "description": "本地桌面端执行型AI助手 - Open Interpreter 风格 | Local Desktop Execution-Oriented AI Assistant",
5
5
  "main": "main.py",
6
6
  "bin": {
@@ -606,6 +606,47 @@ function updateStreamingMessage(msgIdx) {
606
606
  msg._lastStreamRenderedLen = 0;
607
607
  }
608
608
 
609
+ // ── [v1.23.15] 增量渲染文件卡片(v2_file 事件到达时立即显示) ──
610
+ if (msg._files && msg._files.length > 0) {
611
+ var existingFiles = bubbleWrapper ? bubbleWrapper.querySelectorAll(':scope > .msg-attachments') : contentArea.querySelectorAll(':scope > .msg-attachments');
612
+ 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
+ }
622
+ // 只添加未渲染的新文件
623
+ var renderedIds = fileContainer._renderedFileIds || [];
624
+ for (var _fIdx = 0; _fIdx < msg._files.length; _fIdx++) {
625
+ var _f = msg._files[_fIdx];
626
+ var _fId = _f.id || _f.file_id || '';
627
+ if (renderedIds.indexOf(_fId) >= 0) continue;
628
+ var _isImg = _f.type && _f.type.indexOf('image/') === 0;
629
+ var _isAud = _f.type && _f.type.indexOf('audio/') === 0;
630
+ var _isVid = _f.type && _f.type.indexOf('video/') === 0;
631
+ if (_isImg || _isAud || _isVid) { renderedIds.push(_fId); continue; }
632
+ var _icon = _getFileIcon(_f.name || _f.type || '');
633
+ var _sizeStr = _f.size ? formatFileSize(_f.size) : '';
634
+ var _fDiv = document.createElement('div');
635
+ _fDiv.className = 'msg-file-item agent-file';
636
+ _fDiv.title = '点击预览';
637
+ _fDiv.innerHTML = '<span class="msg-file-icon">' + _icon + '</span>' +
638
+ '<span class="msg-file-info"><span class="msg-file-name">' + escapeHtml(_f.name) + '</span>' +
639
+ (_sizeStr ? '<span class="msg-file-size">' + _sizeStr + '</span>' : '') +
640
+ '</span>' +
641
+ '<span class="msg-file-actions">' +
642
+ '<a class="msg-file-download" href="/api/file/' + (_fId || '') + '?name=' + encodeURIComponent(_f.name || 'file') + '" download="' + escapeHtml(_f.name) + '" title="下载" onclick="event.stopPropagation()">⬇</a>' +
643
+ '</span>';
644
+ fileContainer.appendChild(_fDiv);
645
+ renderedIds.push(_fId);
646
+ }
647
+ fileContainer._renderedFileIds = renderedIds;
648
+ }
649
+
609
650
  // Remove exec events panel if present (events are now inline in timeline)
610
651
  const execPanel = contentArea.querySelector('.exec-events-panel');
611
652
  if (execPanel) execPanel.remove();
@@ -1747,6 +1788,10 @@ async function sendMessage(opts) {
1747
1788
  // Flush reasoning text BEFORE tool call to create speak→tool pattern
1748
1789
  flushV2Reasoning();
1749
1790
  flushCurrentText();
1791
+ // [v1.23.15] 清除 _streamingText,防止推理文本在 msgParts(文本段) 和
1792
+ // streaming-segment 中同时渲染导致重复显示
1793
+ state.messages[msgIdx]._streamingText = '';
1794
+ state.messages[msgIdx]._v2Reasoning = '';
1750
1795
  var toolEvent = {
1751
1796
  type: 'v2_tool',
1752
1797
  data: {