myagent-ai 1.15.85 → 1.15.86

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.15.85",
3
+ "version": "1.15.86",
4
4
  "description": "本地桌面端执行型AI助手 - Open Interpreter 风格 | Local Desktop Execution-Oriented AI Assistant",
5
5
  "main": "main.py",
6
6
  "bin": {
@@ -1814,6 +1814,15 @@ input,textarea,select{font:inherit}
1814
1814
  }
1815
1815
  .msg-action-btn:hover{background:var(--bg3);color:var(--accent)}
1816
1816
  .msg-action-btn svg{width:14px;height:14px}
1817
+ .msg-action-btn.tts-speaking{
1818
+ color:var(--accent);opacity:1;
1819
+ animation:ttsBtnPulse 1.2s ease-in-out infinite;
1820
+ }
1821
+ .msg-action-btn.tts-speaking:hover{color:#e74c3c;background:rgba(231,76,60,.1)}
1822
+ @keyframes ttsBtnPulse{
1823
+ 0%,100%{opacity:.7;transform:scale(1)}
1824
+ 50%{opacity:1;transform:scale(1.1)}
1825
+ }
1817
1826
 
1818
1827
  /* TTS playing indicator */
1819
1828
  .tts-playing-icon{
@@ -2520,16 +2520,20 @@ function _renderMessagesInner() {
2520
2520
  <div class="thought-content reasoning-content">${renderMarkdown(msg.reasoning)}</div>
2521
2521
  </details>`;
2522
2522
  })() : '';
2523
+ const _isSpeakingThis = ttsManager && ttsManager.isPlaying && ttsManager.currentMsgIndex === i;
2523
2524
  const actionBtns = (!isUser && msg.content) ? `
2524
2525
  <div class="msg-actions">
2525
2526
  <button class="msg-action-btn" onclick="copyMessage(${i})" title="复制">
2526
2527
  <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
2527
2528
  </button>
2528
- <button class="msg-action-btn" onclick="speakMessage(${i})" title="朗读">
2529
- <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14"/><path d="M15.54 8.46a5 5 0 0 1 0 7.07"/></svg>
2529
+ <button class="msg-action-btn${_isSpeakingThis ? ' tts-speaking' : ''}" onclick="speakMessage(${i})" title="${_isSpeakingThis ? '停止朗读' : '朗读'}">
2530
+ ${_isSpeakingThis
2531
+ ? '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><line x1="23" y1="9" x2="17" y2="15"/><line x1="17" y1="9" x2="23" y2="15"/></svg>'
2532
+ : '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14"/><path d="M15.54 8.46a5 5 0 0 1 0 7.07"/></svg>'
2533
+ }
2530
2534
  </button>
2531
2535
  </div>` : '';
2532
- const ttsIndicator = ttsManager && ttsManager.isPlaying && ttsManager.currentMsgIndex === i ?
2536
+ const ttsIndicator = _isSpeakingThis ?
2533
2537
  ' <span class="tts-playing-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><path d="M15.54 8.46a5 5 0 0 1 0 7.07"/></svg></span>' : '';
2534
2538
 
2535
2539
  // ── Determine rendering mode and streaming indicator ──
@@ -4163,9 +4167,15 @@ function toggleTTS() {
4163
4167
  ttsManager.toggle();
4164
4168
  }
4165
4169
 
4166
- // Speak a specific message
4170
+ // Toggle speak a specific message (click to play, click again to stop)
4167
4171
  function speakMessage(index) {
4168
- ttsManager.speak(index);
4172
+ if (ttsManager.isPlaying && ttsManager.currentMsgIndex === index) {
4173
+ // 正在播放这条消息 → 停止
4174
+ ttsManager.stop();
4175
+ } else {
4176
+ // 没在播放或播放的是别的消息 → 播放这条
4177
+ ttsManager.speak(index);
4178
+ }
4169
4179
  }
4170
4180
 
4171
4181
  // Copy message content to clipboard (assembles full text from all sources)