myagent-ai 1.23.24 → 1.23.25

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.24",
3
+ "version": "1.23.25",
4
4
  "description": "本地桌面端执行型AI助手 - Open Interpreter 风格 | Local Desktop Execution-Oriented AI Assistant",
5
5
  "main": "main.py",
6
6
  "bin": {
@@ -1943,11 +1943,37 @@ async function loadSessions() {
1943
1943
  if (urlSession && state.sessions.some(s => s.id === urlSession)) {
1944
1944
  // URL 指定了有效的 session ID,直接选中(刷新恢复)
1945
1945
  targetSessionId = urlSession;
1946
- } else if (state._pendingSessionRestore && state.sessions.some(s => s.id === state._pendingSessionRestore)) {
1946
+ } else if (urlSession) {
1947
+ // [v1.23.24] 前缀匹配 fallback:前端生成的临时 ID 与后端 canonical ID 可能不同
1948
+ // 例如前端 "default_web_20250101120000" 后端实际为 "default_web_20250101120000_a1b2c3"
1949
+ var prefixMatch = state.sessions.find(function(s) {
1950
+ return s.id.startsWith(urlSession) || urlSession.startsWith(s.id);
1951
+ });
1952
+ if (prefixMatch) {
1953
+ targetSessionId = prefixMatch.id;
1954
+ // 更新 URL 为 canonical ID,避免下次刷新再走 fallback
1955
+ try {
1956
+ var _fixUrl = new URL(window.location.href);
1957
+ _fixUrl.searchParams.set('session', prefixMatch.id);
1958
+ window.history.replaceState({}, '', _fixUrl.toString());
1959
+ } catch (_) {}
1960
+ }
1961
+ }
1962
+ if (!targetSessionId && state._pendingSessionRestore && state.sessions.some(s => s.id === state._pendingSessionRestore)) {
1947
1963
  // 从 localStorage 恢复的 session(beforeunload 触发的保存)
1948
1964
  targetSessionId = state._pendingSessionRestore;
1949
1965
  state._pendingSessionRestore = null; // 清除,防止重复恢复
1950
- } else if (!state.activeSessionId && state.sessions.length > 0) {
1966
+ } else if (!targetSessionId && state._pendingSessionRestore) {
1967
+ // [v1.23.24] localStorage 恢复的 ID 也不匹配,尝试前缀匹配
1968
+ var lsPrefixMatch = state.sessions.find(function(s) {
1969
+ return s.id.startsWith(state._pendingSessionRestore) || state._pendingSessionRestore.startsWith(s.id);
1970
+ });
1971
+ if (lsPrefixMatch) {
1972
+ targetSessionId = lsPrefixMatch.id;
1973
+ }
1974
+ state._pendingSessionRestore = null;
1975
+ }
1976
+ if (!targetSessionId && !state.activeSessionId && state.sessions.length > 0) {
1951
1977
  // 默认选中最新 session
1952
1978
  targetSessionId = state.sessions[0].id;
1953
1979
  }
@@ -1467,9 +1467,22 @@ async function sendMessage(opts) {
1467
1467
  return;
1468
1468
  }
1469
1469
 
1470
+ // [v1.23.24] 立即锁定发送状态,防止竞态导致重复发送
1471
+ // 原因:await checkLargeText() 会 yield 到事件循环,此时 isGenerating 仍为 false
1472
+ // 如果用户再次按 Enter 或点击发送按钮,guard 检查通过,导致重复发送
1473
+ state.isGenerating = true;
1474
+ document.getElementById('sendBtn').style.display = 'none';
1475
+ document.getElementById('stopBtn').style.display = '';
1476
+
1470
1477
  // ── 大文本检测:超过阈值时弹出处理对话框 ──
1471
1478
  var blocked = await checkLargeText(text);
1472
- if (blocked) return;
1479
+ if (blocked) {
1480
+ // 用户取消了大文本发送,释放锁
1481
+ state.isGenerating = false;
1482
+ document.getElementById('sendBtn').style.display = '';
1483
+ document.getElementById('stopBtn').style.display = 'none';
1484
+ return;
1485
+ }
1473
1486
 
1474
1487
  // Create session if needed (incorporate agent name)
1475
1488
  let sessionId = state.activeSessionId;
@@ -1546,12 +1559,9 @@ async function sendMessage(opts) {
1546
1559
  _userScrollLocked = false;
1547
1560
  scrollToBottom(true);
1548
1561
 
1549
- // Show typing
1550
- state.isGenerating = true;
1562
+ // Show typing (isGenerating 和按钮切换已在函数顶部提前设置)
1551
1563
  showTypingIndicator();
1552
1564
  scrollToBottom(true);
1553
- document.getElementById('sendBtn').style.display = 'none';
1554
- document.getElementById('stopBtn').style.display = '';
1555
1565
 
1556
1566
  // Start execution progress polling (in exec mode)
1557
1567
  if (state.chatMode === 'exec') {
@@ -1640,6 +1650,15 @@ async function sendMessage(opts) {
1640
1650
  sessionIdReceived = evt.session_id;
1641
1651
  // Sync the actual session ID (backend may prefix with agent_path)
1642
1652
  state.activeSessionId = evt.session_id;
1653
+ // [v1.23.24] 同步本地 sessions 列表中的 ID(前端生成的临时 ID → 后端 canonical ID)
1654
+ if (sessionIdOriginal && sessionIdOriginal !== evt.session_id) {
1655
+ var _sesIdx = state.sessions.findIndex(function(s) { return s.id === sessionIdOriginal; });
1656
+ if (_sesIdx >= 0) {
1657
+ state.sessions[_sesIdx].id = evt.session_id;
1658
+ state.agentSessions[state.activeAgent] = [...state.sessions];
1659
+ renderSessions();
1660
+ }
1661
+ }
1643
1662
  // ── 更新 URL 参数(后端返回的 session ID 可能与前端不同) ──
1644
1663
  try {
1645
1664
  const _url = new URL(window.location.href);