myagent-ai 1.32.2 → 1.32.4
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/ui/chat/chat_main.js +54 -23
package/package.json
CHANGED
package/web/ui/chat/chat_main.js
CHANGED
|
@@ -2136,10 +2136,16 @@ async function loadAllAgentSessions() {
|
|
|
2136
2136
|
// 快速对话: 选中 agent + 切换执行模式 + 新建会话
|
|
2137
2137
|
function quickChatAgent(agentPath) {
|
|
2138
2138
|
// 选中 agent
|
|
2139
|
+
var _qPrevAgent = state.activeAgent;
|
|
2139
2140
|
state.activeAgent = agentPath;
|
|
2140
2141
|
StatePersistence.save('activeAgent', agentPath);
|
|
2141
2142
|
state.activeSessionId = null;
|
|
2142
2143
|
state.messages = [];
|
|
2144
|
+
// [fix] 切换到不同 agent 时,清除旧 agent 的待恢复会话 ID
|
|
2145
|
+
if (_qPrevAgent !== agentPath) {
|
|
2146
|
+
state._pendingSessionRestore = null;
|
|
2147
|
+
}
|
|
2148
|
+
// [fix] 不再清除 URL ?s= 参数,由 loadSessions 中校验 session 归属来防止错乱
|
|
2143
2149
|
// 展开所有父节点
|
|
2144
2150
|
var parts = agentPath.split('/');
|
|
2145
2151
|
var cumPath = '';
|
|
@@ -2188,10 +2194,21 @@ async function selectAgent(agentPath) {
|
|
|
2188
2194
|
// 移动端:立即关闭右侧栏,不要等异步操作完成
|
|
2189
2195
|
if (isMobile()) closeMobileAgentPanel();
|
|
2190
2196
|
// Always reload sessions even if clicking the same agent
|
|
2197
|
+
var _prevAgent = state.activeAgent;
|
|
2191
2198
|
state.activeAgent = agentPath;
|
|
2192
2199
|
StatePersistence.save('activeAgent', agentPath);
|
|
2193
2200
|
state.activeSessionId = null;
|
|
2194
2201
|
state.messages = [];
|
|
2202
|
+
// [fix] 切换到不同 agent 时,清除旧 agent 的待恢复会话 ID,防止 loadSessions 选中旧 agent 的会话
|
|
2203
|
+
// 注意:仅在 agent 确实发生变化时才清除,避免影响 initChat 中同 agent 的会话恢复逻辑
|
|
2204
|
+
if (_prevAgent !== agentPath) {
|
|
2205
|
+
state._pendingSessionRestore = null;
|
|
2206
|
+
}
|
|
2207
|
+
// [fix] 注意:不再在此处清除 URL 中的 ?s= 参数!
|
|
2208
|
+
// 原因:initChat 恢复场景中,URL 可能同时包含 ?aid=B&s=sess_b1,
|
|
2209
|
+
// 如果在此处删除 s 参数,loadSessions 将无法恢复指定 session。
|
|
2210
|
+
// 正确的做法是在 loadSessions 中校验 URL session 是否属于当前 agent,
|
|
2211
|
+
// 如果不属于则忽略(不选中),从而避免错乱。
|
|
2195
2212
|
// 递增序号,使任何进行中的 selectSession 请求失效
|
|
2196
2213
|
state._sessionLoadSeq++;
|
|
2197
2214
|
var parts = agentPath.split('/');
|
|
@@ -2220,16 +2237,12 @@ async function selectAgent(agentPath) {
|
|
|
2220
2237
|
await loadSessions();
|
|
2221
2238
|
|
|
2222
2239
|
// loadSessions 内部会 auto-select 最新 session;
|
|
2223
|
-
// 如果没有 session
|
|
2240
|
+
// 如果没有 session,则进入"新对话"状态
|
|
2224
2241
|
// [v1.18.9] 如果 loadSessions 已成功选中了 session,不要覆盖其标题
|
|
2225
2242
|
if (!state.activeSessionId || state.activeSessionId === '__new__') {
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
document.getElementById('headerTitle').textContent = '新对话';
|
|
2230
|
-
var details = await loadAgentDetails(agentPath);
|
|
2231
|
-
updateWelcomeCard(agentPath, details);
|
|
2232
|
-
renderMessages();
|
|
2243
|
+
// [fix] 对于没有历史会话的 agent,直接进入新对话状态
|
|
2244
|
+
// 确保 activeSessionId 被设为 '__new__',左侧栏同步显示空列表
|
|
2245
|
+
newChat();
|
|
2233
2246
|
}
|
|
2234
2247
|
// 如果 loadSessions 已经 auto-selected 了 session,UI 已由 selectSession 设置好,不再覆盖
|
|
2235
2248
|
|
|
@@ -2592,9 +2605,25 @@ async function loadSessions() {
|
|
|
2592
2605
|
|
|
2593
2606
|
// 创建新的 Promise 并缓存
|
|
2594
2607
|
const loadPromise = (async () => {
|
|
2608
|
+
// [fix] 在闭包入口捕获当前 agent,防止 await 后 state.activeAgent 被其它 selectAgent 改变
|
|
2609
|
+
// 导致 agent B 的 sessions 被错误地写入 state.agentSessions['C']
|
|
2610
|
+
const loadAgent = currentAgent;
|
|
2595
2611
|
try {
|
|
2596
|
-
const url = `/api/sessions?agent=${encodeURIComponent(
|
|
2612
|
+
const url = `/api/sessions?agent=${encodeURIComponent(loadAgent)}`;
|
|
2597
2613
|
const data = await api(url);
|
|
2614
|
+
// [fix] 竞态保护:如果 await 期间 agent 已切换,不更新 state.sessions(避免覆盖新 agent 的数据)
|
|
2615
|
+
if (state.activeAgent !== loadAgent) {
|
|
2616
|
+
// 仅更新缓存,不动 state.sessions
|
|
2617
|
+
const sessions = (data || []).map(s => ({
|
|
2618
|
+
id: s.id,
|
|
2619
|
+
name: s.display_name || formatSessionName(s.id),
|
|
2620
|
+
messages: s.messages || 0,
|
|
2621
|
+
last: s.last || '',
|
|
2622
|
+
preview: s.preview || '',
|
|
2623
|
+
}));
|
|
2624
|
+
state.agentSessions[loadAgent] = sessions;
|
|
2625
|
+
return { sessions: [], selectedId: null, stale: true };
|
|
2626
|
+
}
|
|
2598
2627
|
state.sessions = (data || []).map(s => ({
|
|
2599
2628
|
id: s.id,
|
|
2600
2629
|
name: s.display_name || formatSessionName(s.id),
|
|
@@ -2602,11 +2631,18 @@ async function loadSessions() {
|
|
|
2602
2631
|
last: s.last || '',
|
|
2603
2632
|
preview: s.preview || '',
|
|
2604
2633
|
}));
|
|
2605
|
-
// Cache per agent
|
|
2606
|
-
state.agentSessions[
|
|
2634
|
+
// Cache per agent — 使用闭包捕获的 loadAgent 而非 state.activeAgent
|
|
2635
|
+
state.agentSessions[loadAgent] = [...state.sessions];
|
|
2607
2636
|
} catch (e) {
|
|
2608
|
-
// Offline - try cache
|
|
2609
|
-
|
|
2637
|
+
// Offline - try cache — 使用 loadAgent
|
|
2638
|
+
if (state.activeAgent === loadAgent) {
|
|
2639
|
+
state.sessions = state.agentSessions[loadAgent] || [];
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
// [fix] 竞态保护:如果 agent 已切换,不渲染 UI、不选中 session
|
|
2644
|
+
if (state.activeAgent !== loadAgent) {
|
|
2645
|
+
return { sessions: [], selectedId: null, stale: true };
|
|
2610
2646
|
}
|
|
2611
2647
|
|
|
2612
2648
|
// Always update session list UI
|
|
@@ -2615,6 +2651,7 @@ async function loadSessions() {
|
|
|
2615
2651
|
|
|
2616
2652
|
// Auto-select most recent session if none selected
|
|
2617
2653
|
// 优先级: URL session 参数 > localStorage 持久化的 session > 最新 session
|
|
2654
|
+
// [fix] 所有候选 session ID 必须属于当前 agent 的会话列表,防止错乱到其它 agent 的历史对话
|
|
2618
2655
|
const urlParams = new URLSearchParams(window.location.search);
|
|
2619
2656
|
const urlSession = UrlCodec.decode(urlParams.get('s') || '') || UrlCodec.decode(urlParams.get('session') || '');
|
|
2620
2657
|
var targetSessionId = null;
|
|
@@ -2656,16 +2693,10 @@ async function loadSessions() {
|
|
|
2656
2693
|
// 默认选中最新 session
|
|
2657
2694
|
targetSessionId = state.sessions[0].id;
|
|
2658
2695
|
}
|
|
2659
|
-
// [v1.24.1
|
|
2660
|
-
//
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
if (fallbackSession && fallbackSession !== '__new__') {
|
|
2664
|
-
targetSessionId = fallbackSession;
|
|
2665
|
-
state._pendingSessionRestore = null;
|
|
2666
|
-
console.log('[loadSessions] Session not in list, force restoring:', targetSessionId);
|
|
2667
|
-
}
|
|
2668
|
-
}
|
|
2696
|
+
// [fix] 移除 v1.24.1 的强制恢复逻辑:不再强制加载不属于当前 agent 的 session ID
|
|
2697
|
+
// 旧逻辑会在 URL/localStorage 残留旧 agent 的 session ID 时,强制加载该会话,
|
|
2698
|
+
// 导致点击新 agent 头像后错乱显示旧 agent 的历史对话。
|
|
2699
|
+
// 对于当前 agent 确实没有匹配 session 的情况,应该进入"新对话"状态,而非加载其它 agent 的会话。
|
|
2669
2700
|
|
|
2670
2701
|
if (targetSessionId) {
|
|
2671
2702
|
await selectSession(targetSessionId);
|