myagent-ai 1.23.79 → 1.23.80
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/myagent/package.json +2 -2
- package/myagent/web/ui/chat/chat.css +4 -2
- package/myagent/web/ui/chat/chat.js +1 -1
- package/myagent/web/ui/chat/chat_container.html +1 -1
- package/myagent/web/ui/chat/chat_main.js +38 -96
- package/myagent/web/ui/chat/groupchat.js +63 -26
- package/package.json +1 -1
- package/web/ui/chat/chat.css +4 -2
- package/web/ui/chat/chat.js +1 -1
- package/web/ui/chat/chat_container.html +1 -1
- package/web/ui/chat/chat_main.js +23 -19
package/myagent/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myagent-ai",
|
|
3
|
-
"version": "1.23.
|
|
3
|
+
"version": "1.23.80",
|
|
4
4
|
"description": "本地桌面端执行型AI助手 - Open Interpreter 风格 | Local Desktop Execution-Oriented AI Assistant",
|
|
5
5
|
"main": "main.py",
|
|
6
6
|
"bin": {
|
|
@@ -43,4 +43,4 @@
|
|
|
43
43
|
"python": ">=3.10",
|
|
44
44
|
"node": ">=18"
|
|
45
45
|
}
|
|
46
|
-
}
|
|
46
|
+
}
|
|
@@ -215,9 +215,10 @@ input,textarea,select{font:inherit}
|
|
|
215
215
|
.messages-container{flex:1;overflow-y:auto;padding:20px}
|
|
216
216
|
.messages-inner{max-width:900px;margin:0 auto;display:flex;flex-direction:column;gap:16px}
|
|
217
217
|
|
|
218
|
-
.message-row{display:flex;gap:10px;animation:msgIn .25s ease-out}
|
|
218
|
+
.message-row{display:flex;gap:10px;animation:msgIn .25s ease-out;align-items:flex-start}
|
|
219
219
|
@keyframes msgIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
|
|
220
220
|
.message-row.user{flex-direction:row-reverse}
|
|
221
|
+
.message-row>:nth-child(2){flex:1;min-width:0}
|
|
221
222
|
|
|
222
223
|
.message-avatar{
|
|
223
224
|
width:32px;height:32px;border-radius:8px;flex-shrink:0;
|
|
@@ -1786,7 +1787,8 @@ input,textarea,select{font:inherit}
|
|
|
1786
1787
|
font-size:12px;color:var(--text3);
|
|
1787
1788
|
animation:msgIn .25s ease-out;
|
|
1788
1789
|
}
|
|
1789
|
-
.group-msg-row{display:flex;gap:10px;animation:msgIn .25s ease-out}
|
|
1790
|
+
.group-msg-row{display:flex;gap:10px;animation:msgIn .25s ease-out;align-items:flex-start}
|
|
1791
|
+
.group-msg-row>:nth-child(2){flex:1;min-width:0}
|
|
1790
1792
|
.group-msg-avatar{
|
|
1791
1793
|
width:32px;height:32px;border-radius:8px;flex-shrink:0;
|
|
1792
1794
|
display:grid;place-items:center;font-size:14px;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
|
6
6
|
<title>MyAgent - AI 助手</title>
|
|
7
|
-
<link rel="stylesheet" href="chat.css?v=
|
|
7
|
+
<link rel="stylesheet" href="chat.css?v=11">
|
|
8
8
|
</head>
|
|
9
9
|
<body>
|
|
10
10
|
<div class="app">
|
|
@@ -91,7 +91,7 @@ function goToAdmin() {
|
|
|
91
91
|
var params = new URLSearchParams();
|
|
92
92
|
var page = 'dashboard';
|
|
93
93
|
// 传递当前聊天状态,供"返回聊天"恢复
|
|
94
|
-
if (state.
|
|
94
|
+
if (state.activeAgent) params.set('from_agent', state.activeAgent);
|
|
95
95
|
if (state.chatMode) params.set('from_mode', state.chatMode);
|
|
96
96
|
if (state.activeSessionId) params.set('from_session', state.activeSessionId);
|
|
97
97
|
if (typeof currentView !== 'undefined' && currentView === 'group' && typeof currentGroupId !== 'undefined' && currentGroupId) {
|
|
@@ -402,8 +402,7 @@ async function initChat() {
|
|
|
402
402
|
loadModels();
|
|
403
403
|
loadStatus();
|
|
404
404
|
loadChatVersion();
|
|
405
|
-
|
|
406
|
-
window._fetchGroupsPromise = fetchGroups();
|
|
405
|
+
fetchGroups();
|
|
407
406
|
fetchDepts();
|
|
408
407
|
// [v1.17.0] 初始化 VNC 远程桌面状态
|
|
409
408
|
refreshVNCStatus();
|
|
@@ -463,7 +462,28 @@ async function initChat() {
|
|
|
463
462
|
document.title = (agentObj ? agentObj.name : urlAgent || 'MyAgent') + ' - MyAgent';
|
|
464
463
|
}
|
|
465
464
|
|
|
466
|
-
|
|
465
|
+
// [v1.23.80] 群聊恢复逻辑(URL 参数优先于 localStorage)
|
|
466
|
+
var _pendingGroupId = urlGroup || state._pendingGroupRestore || null;
|
|
467
|
+
state._pendingGroupRestore = null;
|
|
468
|
+
|
|
469
|
+
function _restoreGroupChat(gid) {
|
|
470
|
+
if (typeof groups !== 'undefined' && groups.length > 0) {
|
|
471
|
+
selectGroup(gid);
|
|
472
|
+
} else {
|
|
473
|
+
setTimeout(function() { _restoreGroupChat(gid); }, 200);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// [v1.23.80] 如果即将恢复群聊,跳过 selectAgent 避免竞态(selectAgent 会清除 currentView=group 状态)
|
|
478
|
+
if (_pendingGroupId) {
|
|
479
|
+
// 群聊模式:不需要 selectAgent,直接恢复群聊视图
|
|
480
|
+
// 但如果有 from_agent 参数,更新 state.activeAgent 以便后续群聊私聊时使用
|
|
481
|
+
if (urlAgent && urlAgent !== state.activeAgent) {
|
|
482
|
+
state.activeAgent = urlAgent;
|
|
483
|
+
StatePersistence.save('activeAgent', urlAgent);
|
|
484
|
+
}
|
|
485
|
+
_restoreGroupChat(_pendingGroupId);
|
|
486
|
+
} else if (urlAgent) {
|
|
467
487
|
// URL 指定了 agent,校验后切换
|
|
468
488
|
var resolved = urlAgent;
|
|
469
489
|
if (!findAgentByPath(resolved)) {
|
|
@@ -498,33 +518,6 @@ async function initChat() {
|
|
|
498
518
|
}
|
|
499
519
|
// 如果 agent 一致,loadSessions() 内部已通过 _pendingSessionRestore 自动处理了
|
|
500
520
|
}
|
|
501
|
-
|
|
502
|
-
// [v1.23.34] 恢复群聊视图(在所有初始化完成后)
|
|
503
|
-
// [v1.23.76] 等待 fetchGroups 完成后再恢复,确保 groups 数组已填充
|
|
504
|
-
var _restoreGroupView = function(gid) {
|
|
505
|
-
if (typeof selectGroup !== 'function') return;
|
|
506
|
-
// 重置滚动锁定状态,确保群聊刷新后能滚到底部
|
|
507
|
-
_userScrollLocked = false;
|
|
508
|
-
selectGroup(gid);
|
|
509
|
-
};
|
|
510
|
-
if (state._pendingGroupRestore) {
|
|
511
|
-
var _gid = state._pendingGroupRestore;
|
|
512
|
-
state._pendingGroupRestore = null;
|
|
513
|
-
// 等待 fetchGroups 完成(如果还在进行中)
|
|
514
|
-
if (window._fetchGroupsPromise) {
|
|
515
|
-
window._fetchGroupsPromise.then(function() { _restoreGroupView(_gid); }).catch(function() { _restoreGroupView(_gid); });
|
|
516
|
-
} else {
|
|
517
|
-
setTimeout(function() { _restoreGroupView(_gid); }, 300);
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
// [v1.23.57] 从后台管理"返回聊天"时,URL 参数优先恢复群聊
|
|
521
|
-
if (urlGroup) {
|
|
522
|
-
if (window._fetchGroupsPromise) {
|
|
523
|
-
window._fetchGroupsPromise.then(function() { _restoreGroupView(urlGroup); }).catch(function() { _restoreGroupView(urlGroup); });
|
|
524
|
-
} else {
|
|
525
|
-
setTimeout(function() { _restoreGroupView(urlGroup); }, 300);
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
521
|
}
|
|
529
522
|
|
|
530
523
|
// Run init: if DOMContentLoaded already fired (dynamic script load), run immediately
|
|
@@ -2140,77 +2133,26 @@ function formatSessionName(id) {
|
|
|
2140
2133
|
|
|
2141
2134
|
function renderSessions(filter = '') {
|
|
2142
2135
|
const list = document.getElementById('sessionList');
|
|
2143
|
-
// [v1.23.
|
|
2136
|
+
// [v1.23.51] 群聊模式下,左侧显示群聊列表而非个人会话
|
|
2144
2137
|
if (currentView === 'group' && typeof groups !== 'undefined' && groups.length > 0) {
|
|
2145
|
-
var currentGroup = null;
|
|
2146
|
-
for (var gi = 0; gi < groups.length; gi++) {
|
|
2147
|
-
if (groups[gi].id === currentGroupId) { currentGroup = groups[gi]; break; }
|
|
2148
|
-
}
|
|
2149
2138
|
var html = '';
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2139
|
+
for (var i = 0; i < groups.length; i++) {
|
|
2140
|
+
var g = groups[i];
|
|
2141
|
+
var isActive = g.id === currentGroupId;
|
|
2142
|
+
var memberCount = (g.members || []).length;
|
|
2143
|
+
html += '<div class="session-item ' + (isActive ? 'active' : '') + '" onclick="selectGroup(\'' + escapeHtml(g.id) + '\')" title="' + escapeHtml(g.name) + '">'
|
|
2144
|
+
+ '<div class="session-icon" style="font-size:16px">' + escapeHtml(g.avatar_emoji || g.emoji || '👥') + '</div>'
|
|
2155
2145
|
+ '<div class="session-info">'
|
|
2156
|
-
+ '<div class="session-name"
|
|
2157
|
-
+ '<div class="session-preview">' + (
|
|
2158
|
-
+ '</div
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
// 显示群内 Agent 成员列表,点击可直接私聊
|
|
2162
|
-
if (currentGroup && currentGroup.members && currentGroup.members.length > 0) {
|
|
2163
|
-
var members = currentGroup.members;
|
|
2164
|
-
// 按角色排序:owner > admin > member
|
|
2165
|
-
members.sort(function(a, b) {
|
|
2166
|
-
var order = {owner: 0, admin: 1, member: 2};
|
|
2167
|
-
return (order[a.role] || 2) - (order[b.role] || 2);
|
|
2168
|
-
});
|
|
2169
|
-
var roleLabel = {owner: '群主', admin: '管理员', member: ''};
|
|
2170
|
-
for (var mi = 0; mi < members.length; mi++) {
|
|
2171
|
-
var m = members[mi];
|
|
2172
|
-
var mPath = m.agent_path || m.path || '';
|
|
2173
|
-
var mName = m.agent_name || m.name || mPath;
|
|
2174
|
-
var mEmoji = m.avatar_emoji || '🤖';
|
|
2175
|
-
var mColor = m.agent_color || (typeof getAgentGradient === 'function' ? getAgentGradient(mName) : 'var(--accent)');
|
|
2176
|
-
var mRole = roleLabel[m.role] || '';
|
|
2177
|
-
// 查找 agent 完整信息
|
|
2178
|
-
var mc = (state.agentsFlat || []).find(function(a) { return a.path === mPath; });
|
|
2179
|
-
if (mc) {
|
|
2180
|
-
mEmoji = mc.avatar_emoji || mEmoji;
|
|
2181
|
-
mColor = mc.avatar_color || mColor;
|
|
2182
|
-
mName = mc.name || mName;
|
|
2183
|
-
}
|
|
2184
|
-
html += '<div class="session-item" onclick="chatWithAgent(\'' + escapeHtml(mPath) + '\')" title="点击与 ' + escapeHtml(mName) + ' 私聊">'
|
|
2185
|
-
+ '<div class="session-icon" style="background:' + escapeHtml(mColor) + ';color:#fff;font-size:14px;border-radius:10px">' + escapeHtml(mEmoji) + '</div>'
|
|
2186
|
-
+ '<div class="session-info">'
|
|
2187
|
-
+ '<div class="session-name">' + escapeHtml(mName) + (mRole ? ' <span style="font-size:11px;color:var(--text3)">' + mRole + '</span>' : '') + '</div>'
|
|
2188
|
-
+ '<div class="session-preview">' + escapeHtml(mPath) + '</div>'
|
|
2189
|
-
+ '</div></div>';
|
|
2190
|
-
}
|
|
2191
|
-
}
|
|
2192
|
-
|
|
2193
|
-
// 底部:其他群聊切换(折叠显示)
|
|
2194
|
-
var otherGroups = groups.filter(function(g) { return g.id !== currentGroupId; });
|
|
2195
|
-
if (otherGroups.length > 0) {
|
|
2196
|
-
html += '<div style="padding:8px 12px;font-size:11px;color:var(--text3);border-top:1px solid var(--border);margin-top:4px">其他群聊</div>';
|
|
2197
|
-
for (var oi = 0; oi < otherGroups.length; oi++) {
|
|
2198
|
-
var og = otherGroups[oi];
|
|
2199
|
-
html += '<div class="session-item" onclick="selectGroup(\'' + escapeHtml(og.id) + '\')" title="切换到 ' + escapeHtml(og.name) + '" style="opacity:0.7">'
|
|
2200
|
-
+ '<div class="session-icon" style="font-size:14px">' + escapeHtml(og.avatar_emoji || og.emoji || '👥') + '</div>'
|
|
2201
|
-
+ '<div class="session-info">'
|
|
2202
|
-
+ '<div class="session-name">' + escapeHtml(og.name) + '</div>'
|
|
2203
|
-
+ '<div class="session-preview">' + ((og.members || []).length) + ' 位成员</div>'
|
|
2204
|
-
+ '</div></div>';
|
|
2205
|
-
}
|
|
2146
|
+
+ '<div class="session-name">' + escapeHtml(g.name) + '</div>'
|
|
2147
|
+
+ '<div class="session-preview">' + escapeHtml(g.description || (memberCount + ' 位成员')) + '</div>'
|
|
2148
|
+
+ '</div>'
|
|
2149
|
+
+ '</div>';
|
|
2206
2150
|
}
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
html += '<div class="session-item" onclick="exitGroupChat()" title="返回个人聊天" style="border-top:1px solid var(--border);margin-top:4px">'
|
|
2151
|
+
// 在列表顶部添加"返回个人聊天"按钮
|
|
2152
|
+
html = '<div class="session-item" onclick="exitGroupChat()" title="返回个人聊天" style="border-bottom:1px solid var(--border);margin-bottom:4px">'
|
|
2210
2153
|
+ '<div class="session-icon" style="font-size:16px">🔙</div>'
|
|
2211
2154
|
+ '<div class="session-info"><div class="session-name">返回个人聊天</div><div class="session-preview">退出群聊视图</div></div>'
|
|
2212
|
-
+ '</div>';
|
|
2213
|
-
|
|
2155
|
+
+ '</div>' + html;
|
|
2214
2156
|
list.innerHTML = html;
|
|
2215
2157
|
return;
|
|
2216
2158
|
}
|
|
@@ -202,6 +202,9 @@ async function selectGroup(gid) {
|
|
|
202
202
|
var dot = document.querySelector('.main-title .dot');
|
|
203
203
|
if (dot) dot.style.display = 'none';
|
|
204
204
|
|
|
205
|
+
// [v1.23.79] 群聊模式:左侧边栏显示群名称 + 成员图标
|
|
206
|
+
renderGroupSidebar(groupData);
|
|
207
|
+
|
|
205
208
|
// Update input placeholder
|
|
206
209
|
document.getElementById('userInput').placeholder = '发送到群聊... (Enter 发送, Shift+Enter 换行)';
|
|
207
210
|
|
|
@@ -223,6 +226,7 @@ async function selectGroup(gid) {
|
|
|
223
226
|
}
|
|
224
227
|
return m;
|
|
225
228
|
});
|
|
229
|
+
if (typeof _userScrollLocked !== 'undefined') _userScrollLocked = false;
|
|
226
230
|
renderGroupMessages();
|
|
227
231
|
} catch (e) {
|
|
228
232
|
toast('加载群聊失败: ' + e.message, 'error');
|
|
@@ -267,38 +271,69 @@ function exitGroupChat() {
|
|
|
267
271
|
renderSessions();
|
|
268
272
|
renderGroups();
|
|
269
273
|
|
|
274
|
+
// [v1.23.79] 恢复侧边栏指示器为当前 Agent
|
|
275
|
+
updateSidebarAgentIndicator();
|
|
276
|
+
|
|
270
277
|
// 重新加载当前 agent 的会话列表和消息
|
|
271
278
|
loadSessions();
|
|
272
279
|
}
|
|
273
280
|
|
|
274
|
-
// [v1.23.
|
|
275
|
-
function
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
281
|
+
// [v1.23.79] 群聊时左侧边栏显示群成员列表,点击可私聊
|
|
282
|
+
function renderGroupSidebar(groupData) {
|
|
283
|
+
var indicator = document.getElementById('sidebarAgentIndicator');
|
|
284
|
+
var avatar = document.getElementById('sidebarAgentAvatar');
|
|
285
|
+
var nameEl = document.getElementById('sidebarAgentName');
|
|
286
|
+
var hintEl = document.getElementById('sidebarAgentHint');
|
|
287
|
+
if (!indicator || !groupData) return;
|
|
288
|
+
|
|
289
|
+
// 顶部显示群名称
|
|
290
|
+
indicator.style.display = 'flex';
|
|
291
|
+
indicator.style.background = groupData.avatar_color ? groupData.avatar_color + '18' : 'var(--accent-light)';
|
|
292
|
+
indicator.onclick = function() { if (typeof showGroupSettingsModal === 'function') showGroupSettingsModal(); };
|
|
293
|
+
var emoji = groupData.avatar_emoji || groupData.emoji || '👥';
|
|
294
|
+
avatar.textContent = emoji;
|
|
295
|
+
avatar.style.background = groupData.avatar_color || 'var(--accent)';
|
|
296
|
+
avatar.style.color = '#fff';
|
|
297
|
+
nameEl.textContent = groupData.name || '群聊';
|
|
298
|
+
var memberCount = (groupData.members || []).length;
|
|
299
|
+
hintEl.textContent = memberCount + ' 位成员';
|
|
300
|
+
|
|
301
|
+
// 隐藏"新对话"按钮
|
|
286
302
|
var newChatBtn = document.querySelector('.new-chat-btn');
|
|
287
|
-
if (newChatBtn) newChatBtn.style.display = '';
|
|
288
|
-
var searchInput = document.getElementById('searchInput');
|
|
289
|
-
if (searchInput) { searchInput.placeholder = '搜索对话...'; searchInput.value = ''; }
|
|
290
|
-
document.getElementById('activeAgentBadge').style.display = '';
|
|
291
|
-
document.getElementById('groupBackBtn').style.display = 'none';
|
|
292
|
-
document.getElementById('groupSettingsBtn').style.display = 'none';
|
|
293
|
-
var atAllBtn = document.getElementById('atAllBtn');
|
|
294
|
-
if (atAllBtn) atAllBtn.style.display = 'none';
|
|
295
|
-
var _ccb = document.getElementById('clearChatBtn'); if (_ccb) _ccb.style.display = '';
|
|
296
|
-
var dot = document.querySelector('.main-title .dot');
|
|
297
|
-
if (dot) dot.style.display = '';
|
|
298
|
-
document.getElementById('userInput').placeholder = '输入消息... (Enter 发送, Shift+Enter 换行)';
|
|
303
|
+
if (newChatBtn) newChatBtn.style.display = 'none';
|
|
299
304
|
|
|
300
|
-
//
|
|
305
|
+
// 在会话列表区域显示群成员
|
|
306
|
+
var list = document.getElementById('sessionList');
|
|
307
|
+
if (!list) return;
|
|
308
|
+
var members = groupData.members || [];
|
|
309
|
+
var html = '<div class="session-item" onclick="exitGroupChat()" title="返回个人聊天" style="border-bottom:1px solid var(--border);margin-bottom:4px">'
|
|
310
|
+
+ '<div class="session-icon" style="font-size:16px">🔙</div>'
|
|
311
|
+
+ '<div class="session-info"><div class="session-name">返回个人聊天</div><div class="session-preview">退出群聊视图</div></div>'
|
|
312
|
+
+ '</div>';
|
|
313
|
+
|
|
314
|
+
// 显示群成员列表,点击直接私聊
|
|
315
|
+
for (var i = 0; i < members.length; i++) {
|
|
316
|
+
var m = members[i];
|
|
317
|
+
var mEmoji = m.avatar_emoji || '🤖';
|
|
318
|
+
var mName = m.agent_name || m.name || m.agent_path || 'Unknown';
|
|
319
|
+
var mPath = m.agent_path || m.path || '';
|
|
320
|
+
var mColor = m.agent_color || getAgentGradient(mName);
|
|
321
|
+
var mRole = m.role || 'member';
|
|
322
|
+
var roleLabel = {owner: '群主', admin: '管理员', member: '成员'}[mRole] || '';
|
|
323
|
+
html += '<div class="session-item" onclick="startPrivateChatFromGroup(\'' + escapeHtml(mPath) + '\')" title="私聊 ' + escapeHtml(mName) + '">'
|
|
324
|
+
+ '<div class="session-icon" style="font-size:16px;background:' + mColor + ';color:#fff;border-radius:50%;width:32px;height:32px;display:grid;place-items:center">' + escapeHtml(mEmoji) + '</div>'
|
|
325
|
+
+ '<div class="session-info">'
|
|
326
|
+
+ '<div class="session-name">' + escapeHtml(mName) + (roleLabel ? ' <span style="font-size:10px;color:var(--text3);font-weight:normal">' + roleLabel + '</span>' : '') + '</div>'
|
|
327
|
+
+ '<div class="session-preview">' + escapeHtml(mPath) + '</div>'
|
|
328
|
+
+ '</div></div>';
|
|
329
|
+
}
|
|
330
|
+
list.innerHTML = html;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// [v1.23.79] 从群聊成员列表点击,直接发起私聊
|
|
334
|
+
function startPrivateChatFromGroup(agentPath) {
|
|
301
335
|
if (typeof selectAgent === 'function') {
|
|
336
|
+
exitGroupChat();
|
|
302
337
|
selectAgent(agentPath);
|
|
303
338
|
}
|
|
304
339
|
}
|
|
@@ -392,7 +427,7 @@ function _renderGroupMessagesInner() {
|
|
|
392
427
|
}
|
|
393
428
|
});
|
|
394
429
|
});
|
|
395
|
-
scrollToBottom();
|
|
430
|
+
if (typeof scrollToBottom === 'function') scrollToBottom(true);
|
|
396
431
|
}
|
|
397
432
|
|
|
398
433
|
// ══════════════════════════════════════════════════════
|
|
@@ -853,6 +888,7 @@ async function sendGroupChat() {
|
|
|
853
888
|
|
|
854
889
|
// Add user message
|
|
855
890
|
groupMessages.push({role: 'user', content: text, time: new Date().toISOString()});
|
|
891
|
+
if (typeof _userScrollLocked !== 'undefined') _userScrollLocked = false;
|
|
856
892
|
renderGroupMessages();
|
|
857
893
|
|
|
858
894
|
// Clear input
|
|
@@ -878,6 +914,7 @@ async function sendGroupChat() {
|
|
|
878
914
|
groupMessages.push({type: 'system', content: data.system_message, time: new Date().toISOString()});
|
|
879
915
|
}
|
|
880
916
|
|
|
917
|
+
if (typeof _userScrollLocked !== 'undefined') _userScrollLocked = false;
|
|
881
918
|
renderGroupMessages();
|
|
882
919
|
fetchGroups();
|
|
883
920
|
} catch (e) {
|
package/package.json
CHANGED
package/web/ui/chat/chat.css
CHANGED
|
@@ -215,9 +215,10 @@ input,textarea,select{font:inherit}
|
|
|
215
215
|
.messages-container{flex:1;overflow-y:auto;padding:20px}
|
|
216
216
|
.messages-inner{max-width:900px;margin:0 auto;display:flex;flex-direction:column;gap:16px}
|
|
217
217
|
|
|
218
|
-
.message-row{display:flex;gap:10px;animation:msgIn .25s ease-out}
|
|
218
|
+
.message-row{display:flex;gap:10px;animation:msgIn .25s ease-out;align-items:flex-start}
|
|
219
219
|
@keyframes msgIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
|
|
220
220
|
.message-row.user{flex-direction:row-reverse}
|
|
221
|
+
.message-row>:nth-child(2){flex:1;min-width:0}
|
|
221
222
|
|
|
222
223
|
.message-avatar{
|
|
223
224
|
width:32px;height:32px;border-radius:8px;flex-shrink:0;
|
|
@@ -1786,7 +1787,8 @@ input,textarea,select{font:inherit}
|
|
|
1786
1787
|
font-size:12px;color:var(--text3);
|
|
1787
1788
|
animation:msgIn .25s ease-out;
|
|
1788
1789
|
}
|
|
1789
|
-
.group-msg-row{display:flex;gap:10px;animation:msgIn .25s ease-out}
|
|
1790
|
+
.group-msg-row{display:flex;gap:10px;animation:msgIn .25s ease-out;align-items:flex-start}
|
|
1791
|
+
.group-msg-row>:nth-child(2){flex:1;min-width:0}
|
|
1790
1792
|
.group-msg-avatar{
|
|
1791
1793
|
width:32px;height:32px;border-radius:8px;flex-shrink:0;
|
|
1792
1794
|
display:grid;place-items:center;font-size:14px;
|
package/web/ui/chat/chat.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
|
6
6
|
<title>MyAgent - AI 助手</title>
|
|
7
|
-
<link rel="stylesheet" href="chat.css?v=
|
|
7
|
+
<link rel="stylesheet" href="chat.css?v=11">
|
|
8
8
|
</head>
|
|
9
9
|
<body>
|
|
10
10
|
<div class="app">
|
package/web/ui/chat/chat_main.js
CHANGED
|
@@ -91,7 +91,7 @@ function goToAdmin() {
|
|
|
91
91
|
var params = new URLSearchParams();
|
|
92
92
|
var page = 'dashboard';
|
|
93
93
|
// 传递当前聊天状态,供"返回聊天"恢复
|
|
94
|
-
if (state.
|
|
94
|
+
if (state.activeAgent) params.set('from_agent', state.activeAgent);
|
|
95
95
|
if (state.chatMode) params.set('from_mode', state.chatMode);
|
|
96
96
|
if (state.activeSessionId) params.set('from_session', state.activeSessionId);
|
|
97
97
|
if (typeof currentView !== 'undefined' && currentView === 'group' && typeof currentGroupId !== 'undefined' && currentGroupId) {
|
|
@@ -462,7 +462,28 @@ async function initChat() {
|
|
|
462
462
|
document.title = (agentObj ? agentObj.name : urlAgent || 'MyAgent') + ' - MyAgent';
|
|
463
463
|
}
|
|
464
464
|
|
|
465
|
-
|
|
465
|
+
// [v1.23.80] 群聊恢复逻辑(URL 参数优先于 localStorage)
|
|
466
|
+
var _pendingGroupId = urlGroup || state._pendingGroupRestore || null;
|
|
467
|
+
state._pendingGroupRestore = null;
|
|
468
|
+
|
|
469
|
+
function _restoreGroupChat(gid) {
|
|
470
|
+
if (typeof groups !== 'undefined' && groups.length > 0) {
|
|
471
|
+
selectGroup(gid);
|
|
472
|
+
} else {
|
|
473
|
+
setTimeout(function() { _restoreGroupChat(gid); }, 200);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// [v1.23.80] 如果即将恢复群聊,跳过 selectAgent 避免竞态(selectAgent 会清除 currentView=group 状态)
|
|
478
|
+
if (_pendingGroupId) {
|
|
479
|
+
// 群聊模式:不需要 selectAgent,直接恢复群聊视图
|
|
480
|
+
// 但如果有 from_agent 参数,更新 state.activeAgent 以便后续群聊私聊时使用
|
|
481
|
+
if (urlAgent && urlAgent !== state.activeAgent) {
|
|
482
|
+
state.activeAgent = urlAgent;
|
|
483
|
+
StatePersistence.save('activeAgent', urlAgent);
|
|
484
|
+
}
|
|
485
|
+
_restoreGroupChat(_pendingGroupId);
|
|
486
|
+
} else if (urlAgent) {
|
|
466
487
|
// URL 指定了 agent,校验后切换
|
|
467
488
|
var resolved = urlAgent;
|
|
468
489
|
if (!findAgentByPath(resolved)) {
|
|
@@ -497,23 +518,6 @@ async function initChat() {
|
|
|
497
518
|
}
|
|
498
519
|
// 如果 agent 一致,loadSessions() 内部已通过 _pendingSessionRestore 自动处理了
|
|
499
520
|
}
|
|
500
|
-
|
|
501
|
-
// [v1.23.79] 群聊恢复:等待 groups 加载完毕后再 selectGroup
|
|
502
|
-
function _restoreGroupChat(gid) {
|
|
503
|
-
if (typeof groups !== 'undefined' && groups.length > 0) {
|
|
504
|
-
selectGroup(gid);
|
|
505
|
-
} else {
|
|
506
|
-
setTimeout(function() { _restoreGroupChat(gid); }, 200);
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
if (state._pendingGroupRestore && typeof selectGroup === 'function') {
|
|
510
|
-
var _gid = state._pendingGroupRestore;
|
|
511
|
-
state._pendingGroupRestore = null;
|
|
512
|
-
_restoreGroupChat(_gid);
|
|
513
|
-
}
|
|
514
|
-
if (urlGroup && typeof selectGroup === 'function') {
|
|
515
|
-
_restoreGroupChat(urlGroup);
|
|
516
|
-
}
|
|
517
521
|
}
|
|
518
522
|
|
|
519
523
|
// Run init: if DOMContentLoaded already fired (dynamic script load), run immediately
|