myagent-ai 1.15.22 → 1.15.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 +1 -1
- package/web/ui/chat/chat.css +4 -4
- package/web/ui/chat/chat.js +16 -39
- package/web/ui/chat/chat_container.html +256 -12
- package/web/ui/index.html +1 -1
package/package.json
CHANGED
package/web/ui/chat/chat.css
CHANGED
|
@@ -49,10 +49,10 @@ input,textarea,select{font:inherit}
|
|
|
49
49
|
/* ── Layout ── */
|
|
50
50
|
.app{position:fixed;top:0;left:0;width:100vw;height:100vh;display:flex;overflow:hidden;background:var(--bg)}
|
|
51
51
|
|
|
52
|
-
/*
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
/* Layout panels */
|
|
53
|
+
.sidebar,
|
|
54
|
+
.agent-panel{flex-shrink:0;height:100%}
|
|
55
|
+
.main{flex:1;display:flex;flex-direction:column;min-width:0;height:100%;overflow:hidden}
|
|
56
56
|
|
|
57
57
|
/* ── Sidebar ── */
|
|
58
58
|
.sidebar{
|
package/web/ui/chat/chat.js
CHANGED
|
@@ -1,45 +1,22 @@
|
|
|
1
|
-
// ──
|
|
2
|
-
//
|
|
1
|
+
// ── Script loader (no HTML fragments) ──
|
|
2
|
+
// HTML structure is now inlined in chat_container.html, only load JS scripts
|
|
3
3
|
|
|
4
4
|
(function() {
|
|
5
5
|
var base = new URL('.', window.location.href).href;
|
|
6
|
-
var v = '?v=
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
var v = '?v=8';
|
|
7
|
+
var scripts = [
|
|
8
|
+
'groupchat.js', // 群聊模块(状态 + API + 渲染 + 发送)
|
|
9
|
+
'flow_engine.js', // 文本处理流引擎(SSE 流式 + 大文本 + 执行事件)
|
|
10
|
+
'chat_main.js', // 核心 UI 逻辑(状态管理 + 渲染 + 会话 + 侧边栏)
|
|
11
11
|
];
|
|
12
|
-
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
return Promise.all(promises);
|
|
12
|
+
var idx = 0;
|
|
13
|
+
function loadNext() {
|
|
14
|
+
if (idx >= scripts.length) return;
|
|
15
|
+
var s = document.createElement('script');
|
|
16
|
+
s.src = base + scripts[idx] + v;
|
|
17
|
+
s.onload = function() { idx++; loadNext(); };
|
|
18
|
+
s.onerror = function() { console.error('Failed to load: ' + scripts[idx]); idx++; loadNext(); };
|
|
19
|
+
document.body.appendChild(s);
|
|
23
20
|
}
|
|
24
|
-
|
|
25
|
-
// Load fragments, then inject scripts in dependency order
|
|
26
|
-
loadAll().then(function() {
|
|
27
|
-
var scripts = [
|
|
28
|
-
'groupchat.js', // 群聊模块(状态 + API + 渲染 + 发送)
|
|
29
|
-
'flow_engine.js', // 文本处理流引擎(SSE 流式 + 大文本 + 执行事件)
|
|
30
|
-
'chat_main.js', // 核心 UI 逻辑(状态管理 + 渲染 + 会话 + 侧边栏)
|
|
31
|
-
];
|
|
32
|
-
var idx = 0;
|
|
33
|
-
function loadNext() {
|
|
34
|
-
if (idx >= scripts.length) return;
|
|
35
|
-
var s = document.createElement('script');
|
|
36
|
-
s.src = base + scripts[idx] + v;
|
|
37
|
-
s.onload = function() { idx++; loadNext(); };
|
|
38
|
-
s.onerror = function() { console.error('Failed to load: ' + scripts[idx]); idx++; loadNext(); };
|
|
39
|
-
document.body.appendChild(s);
|
|
40
|
-
}
|
|
41
|
-
loadNext();
|
|
42
|
-
}).catch(function(err) {
|
|
43
|
-
console.error('Failed to load chat fragments:', err);
|
|
44
|
-
});
|
|
21
|
+
loadNext();
|
|
45
22
|
})();
|
|
@@ -4,33 +4,277 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>MyAgent - AI 助手</title>
|
|
7
|
-
<link rel="stylesheet" href="chat.css?v=
|
|
7
|
+
<link rel="stylesheet" href="chat.css?v=7">
|
|
8
8
|
</head>
|
|
9
9
|
<body>
|
|
10
10
|
<div class="app">
|
|
11
|
-
<!-- Placeholder: Left Sessions (loaded from left_sessions.html) -->
|
|
12
|
-
<div id="leftSessionsContainer"></div>
|
|
13
11
|
|
|
14
|
-
<!--
|
|
15
|
-
<div id="
|
|
12
|
+
<!-- ═══ Left Sidebar: Sessions ═══ -->
|
|
13
|
+
<div class="sidebar" id="sidebar">
|
|
14
|
+
<div class="sidebar-toggle" onclick="toggleSidebar()" id="sidebarToggle" title="收起侧边栏">◀</div>
|
|
15
|
+
<div class="mobile-panel-close-btn" id="mobileSidebarCloseBtn" onclick="closeMobileSidebar()" title="返回聊天">
|
|
16
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="20" height="20"><polyline points="15 18 9 12 15 6"/></svg>
|
|
17
|
+
<span>返回聊天</span>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="sidebar-header">
|
|
20
|
+
<div class="sidebar-logo">
|
|
21
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
|
|
22
|
+
</div>
|
|
23
|
+
<div>
|
|
24
|
+
<div class="sidebar-title">MyAgent</div>
|
|
25
|
+
<div class="sidebar-subtitle">AI 助手</div>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<button class="new-chat-btn" onclick="newChat()">
|
|
30
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
|
31
|
+
新对话
|
|
32
|
+
</button>
|
|
33
|
+
|
|
34
|
+
<div class="sidebar-search">
|
|
35
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
|
36
|
+
<input type="text" placeholder="搜索对话..." id="searchInput" oninput="filterSessions()">
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<div id="sidebarAgentIndicator" style="padding:6px 16px;display:none;align-items:center;gap:8px;border-bottom:1px solid var(--border-light);background:var(--accent-light);cursor:pointer" onclick="document.getElementById('agentPanel').classList.remove('collapsed')">
|
|
40
|
+
<div id="sidebarAgentAvatar" style="width:24px;height:24px;border-radius:6px;display:grid;place-items:center;font-size:12px;color:#fff;flex-shrink:0"></div>
|
|
41
|
+
<div style="flex:1;min-width:0">
|
|
42
|
+
<div id="sidebarAgentName" style="font-size:12px;font-weight:600;color:var(--accent);white-space:nowrap;overflow:hidden;text-overflow:ellipsis"></div>
|
|
43
|
+
<div id="sidebarAgentHint" style="font-size:10px;color:var(--text3)"></div>
|
|
44
|
+
</div>
|
|
45
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="var(--text3)" stroke-width="2"><path d="M9 18l6-6-6-6"/></svg>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<div class="sidebar-scroll" id="sidebarScroll">
|
|
49
|
+
<div class="session-list" id="sessionList"></div>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div class="sidebar-footer">
|
|
53
|
+
<button class="sidebar-footer-btn" onclick="window.location.href='/ui/index.html'">
|
|
54
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
|
|
55
|
+
后台管理
|
|
56
|
+
</button>
|
|
57
|
+
<div class="sidebar-version-bar">
|
|
58
|
+
<span id="chatVersion" style="font-size:11px;color:var(--text3)"></span>
|
|
59
|
+
<span id="chatUpdateBadge" style="display:none;font-size:11px;color:var(--danger);cursor:pointer" onclick="doChatUpdate()" title="点击更新">[可更新]</span>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<!-- ═══ Middle: Chat Area ═══ -->
|
|
65
|
+
<div class="main" id="mainArea">
|
|
66
|
+
<div class="main-header">
|
|
67
|
+
<button class="toggle-sidebar" onclick="toggleSidebar()" title="切换侧栏">
|
|
68
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="15" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
|
|
69
|
+
</button>
|
|
70
|
+
<div class="main-title">
|
|
71
|
+
<span class="dot"></span>
|
|
72
|
+
<span id="headerTitle"></span>
|
|
73
|
+
<span class="active-agent-badge" id="activeAgentBadge" style="display:none">
|
|
74
|
+
<span class="badge-avatar" id="badgeAvatar"></span>
|
|
75
|
+
<span id="badgeName"></span>
|
|
76
|
+
</span>
|
|
77
|
+
</div>
|
|
78
|
+
<div class="header-actions">
|
|
79
|
+
<button class="header-btn" id="mobileAgentsBtn" onclick="toggleMobileAgentPanel()" title="Agents" style="display:none">
|
|
80
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
|
|
81
|
+
</button>
|
|
82
|
+
<button class="header-btn" id="groupBackBtn" onclick="exitGroupChat()" title="返回对话" style="display:none">
|
|
83
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 18 9 12 15 6"/></svg>
|
|
84
|
+
</button>
|
|
85
|
+
<button class="header-btn" id="groupSettingsBtn" onclick="showGroupSettingsModal()" title="群聊设置" style="display:none">
|
|
86
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
|
|
87
|
+
</button>
|
|
88
|
+
<div style="position:relative">
|
|
89
|
+
<button class="speaker-btn" id="ttsToggleBtn" onclick="toggleTTS()" title="语音朗读 (TTS)">
|
|
90
|
+
<svg id="ttsIconOff" 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"/><line x1="23" y1="9" x2="17" y2="15"/><line x1="17" y1="9" x2="23" y2="15"/></svg>
|
|
91
|
+
<svg id="ttsIconOn" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display:none"><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>
|
|
92
|
+
</button>
|
|
93
|
+
</div>
|
|
94
|
+
<button class="header-btn" id="themeToggle" title="切换主题">
|
|
95
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
|
|
96
|
+
</button>
|
|
97
|
+
<button class="header-btn" id="popoutBtn" onclick="popoutChat()" title="弹出独立窗口">
|
|
98
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/><path d="M21 14v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h5"/></svg>
|
|
99
|
+
</button>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<div class="messages-container" id="messagesContainer">
|
|
104
|
+
<div class="messages-inner" id="messagesInner"></div>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<!-- Task Plan Panel -->
|
|
108
|
+
<div class="task-panel hidden" id="taskPanel">
|
|
109
|
+
<div class="task-panel-header" onclick="toggleTaskPanel()">
|
|
110
|
+
<span class="tp-icon">📋</span>
|
|
111
|
+
<span class="tp-title">任务计划 (task.md)</span>
|
|
112
|
+
<span class="tp-count" id="taskCount">0</span>
|
|
113
|
+
<span class="tp-toggle" id="taskToggle"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"/></svg></span>
|
|
114
|
+
</div>
|
|
115
|
+
<div class="task-panel-body" id="taskBody">
|
|
116
|
+
<div class="task-list" id="taskList"></div>
|
|
117
|
+
<div class="task-add-row">
|
|
118
|
+
<input class="task-add-input" id="taskAddInput" placeholder="添加新任务..." onkeydown="if(event.key==='Enter')addTaskItem()">
|
|
119
|
+
<button class="task-add-btn" onclick="addTaskItem()">+ 添加</button>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<!-- Input -->
|
|
125
|
+
<div class="input-area">
|
|
126
|
+
<div class="input-wrapper">
|
|
127
|
+
<div style="display:flex;align-items:center;gap:8px;margin-bottom:10px;flex-wrap:wrap;">
|
|
128
|
+
<div class="mode-toggle">
|
|
129
|
+
<button class="mode-btn active-chat" id="modeChatBtn" onclick="setMode('chat')">
|
|
130
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
|
|
131
|
+
💬 聊天
|
|
132
|
+
</button>
|
|
133
|
+
<button class="mode-btn" id="modeExecBtn" onclick="setMode('exec')">
|
|
134
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>
|
|
135
|
+
⚡ 执行
|
|
136
|
+
</button>
|
|
137
|
+
</div>
|
|
138
|
+
<div class="input-mode-toggle">
|
|
139
|
+
<button class="input-mode-btn active" id="inputModeTextBtn" onclick="switchInputMode('text')" title="键盘输入">
|
|
140
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="4" width="20" height="16" rx="2"/><line x1="6" y1="8" x2="6" y2="8"/><line x1="10" y1="8" x2="10" y2="8"/><line x1="14" y1="8" x2="14" y2="8"/><line x1="18" y1="8" x2="18" y2="8"/><line x1="8" y1="12" x2="8" y2="12"/><line x1="12" y1="12" x2="12" y2="12"/><line x1="16" y1="12" x2="16" y2="12"/><line x1="6" y1="16" x2="18" y2="16"/></svg>
|
|
141
|
+
</button>
|
|
142
|
+
<button class="input-mode-btn" id="inputModeVoiceBtn" onclick="switchInputMode('voice')" title="语音输入">
|
|
143
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/><line x1="8" y1="23" x2="16" y2="23"/></svg>
|
|
144
|
+
</button>
|
|
145
|
+
</div>
|
|
146
|
+
<div class="exec-mode-toggle" id="execModeToggle">
|
|
147
|
+
<div class="exec-mode-info" id="execModeInfo">
|
|
148
|
+
<span class="exec-mode-dot sandbox" id="execModeDot"></span>
|
|
149
|
+
<span class="exec-mode-label" id="execModeLabel"></span>
|
|
150
|
+
</div>
|
|
151
|
+
<button class="exec-mode-btn" id="execModeBtn" onclick="toggleExecMode()" title="切换执行模式">
|
|
152
|
+
<span id="execModeBtnText"></span>
|
|
153
|
+
</button>
|
|
154
|
+
</div>
|
|
155
|
+
<div class="lock-indicator hidden" id="lockIndicator" onclick="showLockInfo()" title="全局执行锁">
|
|
156
|
+
<span class="lock-icon">🔒</span>
|
|
157
|
+
<span class="lock-text" id="lockText"></span>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
<div class="input-box" id="inputBox">
|
|
161
|
+
<div class="text-input-area" id="textInputArea">
|
|
162
|
+
<textarea id="userInput" placeholder="输入消息... (Enter 发送, Shift+Enter 换行)" rows="1" onkeydown="handleKeyDown(event)" oninput="autoResize(this)"></textarea>
|
|
163
|
+
<button class="send-btn" id="sendBtn" onclick="sendMessage()" disabled>
|
|
164
|
+
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>
|
|
165
|
+
</button>
|
|
166
|
+
<button class="stop-btn" id="stopBtn" onclick="stopGenerating()" style="display:none">
|
|
167
|
+
<svg viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="6" width="12" height="12" rx="2"/></svg>
|
|
168
|
+
</button>
|
|
169
|
+
</div>
|
|
170
|
+
<div class="voice-input-area" id="voiceInputArea" style="display:none">
|
|
171
|
+
<button class="voice-record-btn" id="voiceRecordBtn">
|
|
172
|
+
<svg class="voice-icon-mic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/><line x1="8" y1="23" x2="16" y2="23"/></svg>
|
|
173
|
+
<svg class="voice-icon-wave" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display:none"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/><line x1="8" y1="23" x2="16" y2="23"/></svg>
|
|
174
|
+
<span class="voice-btn-text">按住说话</span>
|
|
175
|
+
</button>
|
|
176
|
+
<div class="voice-status" id="voiceStatus"></div>
|
|
177
|
+
</div>
|
|
178
|
+
<div class="voice-preview" id="voicePreview" style="display:none">
|
|
179
|
+
<div class="voice-preview-label">语音输入 · <span id="voicePreviewHint">识别中...</span></div>
|
|
180
|
+
<div class="voice-preview-text" id="voicePreviewText"></div>
|
|
181
|
+
<div class="voice-preview-actions">
|
|
182
|
+
<button class="voice-preview-cancel" onclick="cancelVoicePreview()">取消</button>
|
|
183
|
+
<button class="voice-preview-send" id="voicePreviewSend" onclick="sendVoiceMessage()">发送</button>
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
187
|
+
<div class="input-hint">MyAgent 可能会出错,请核实重要信息</div>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
|
|
191
|
+
<!-- Inject Modal -->
|
|
192
|
+
<div id="injectModal" class="modal-overlay" style="display:none">
|
|
193
|
+
<div class="modal">
|
|
194
|
+
<h3>任务执行中</h3>
|
|
195
|
+
<p>Agent 正在执行任务,请选择如何处理你的消息:</p>
|
|
196
|
+
<div style="display:flex;flex-direction:column;gap:8px;margin-bottom:0">
|
|
197
|
+
<button class="modal-btn" style="width:100%;justify-content:center;background:var(--accent);color:#fff" onclick="handleInjectChoice('queue')">排队等待</button>
|
|
198
|
+
<button class="modal-btn" style="width:100%;justify-content:center" onclick="handleInjectChoice('inject')">注入当前任务</button>
|
|
199
|
+
<button class="modal-btn" style="width:100%;justify-content:center;color:var(--text2)" onclick="closeInjectModal()">取消</button>
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
<!-- ═══ Right Panel: Agents ═══ -->
|
|
206
|
+
<div class="agent-panel" id="agentPanel">
|
|
207
|
+
<div class="agent-toggle" onclick="toggleAgentPanel()" id="agentToggle" title="收起面板">▶</div>
|
|
208
|
+
<div class="mobile-panel-close-btn" id="mobileAgentCloseBtn" onclick="closeMobileAgentPanel()" title="返回聊天">
|
|
209
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="20" height="20"><polyline points="9 18 15 12 9 6"/></svg>
|
|
210
|
+
<span>返回聊天</span>
|
|
211
|
+
</div>
|
|
212
|
+
<div class="agent-panel-header">
|
|
213
|
+
<h3><span class="agents-emoji">🤖</span> Agents</h3>
|
|
214
|
+
<button class="agent-manage-btn" onclick="window.location.href='/ui/index.html?page=agents'" title="Agent 管理后台">
|
|
215
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>
|
|
216
|
+
</button>
|
|
217
|
+
<button class="agent-create-btn" onclick="showCreateAgentModal()" title="创建新 Agent">
|
|
218
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
|
219
|
+
</button>
|
|
220
|
+
</div>
|
|
221
|
+
|
|
222
|
+
<div class="agent-list" id="agentList">
|
|
223
|
+
<div id="rpMasterAgent"></div>
|
|
224
|
+
<div id="rpRecentSection" style="display:none">
|
|
225
|
+
<div class="rp-section-header" onclick="toggleRpSection('recent')">
|
|
226
|
+
<span class="rp-section-title">🕐 最近对话</span>
|
|
227
|
+
<span class="rp-section-toggle expanded" id="rpRecentToggle">▶</span>
|
|
228
|
+
</div>
|
|
229
|
+
<div class="rp-section-body" id="rpRecentBody">
|
|
230
|
+
<div class="rp-recent-grid" id="rpRecentGrid"></div>
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
<div id="rpDeptSection">
|
|
234
|
+
<div class="rp-section-header" onclick="toggleRpSection('dept')">
|
|
235
|
+
<span class="rp-section-title">🏢 部门</span>
|
|
236
|
+
<span class="rp-section-toggle" id="rpDeptToggle">▶</span>
|
|
237
|
+
</div>
|
|
238
|
+
<div class="rp-section-body" id="rpDeptBody" style="display:none"></div>
|
|
239
|
+
</div>
|
|
240
|
+
<div id="rpGroupSection">
|
|
241
|
+
<div class="rp-section-header" onclick="toggleRpSection('group')">
|
|
242
|
+
<span class="rp-section-title">👥 群聊</span>
|
|
243
|
+
<div style="display:flex;align-items:center;gap:4px">
|
|
244
|
+
<button class="rp-section-action-btn" onclick="event.stopPropagation();showCreateGroupModal()" title="创建群聊">
|
|
245
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:14px;height:14px"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
|
246
|
+
</button>
|
|
247
|
+
<span class="rp-section-toggle expanded" id="rpGroupToggle">▶</span>
|
|
248
|
+
</div>
|
|
249
|
+
</div>
|
|
250
|
+
<div class="rp-section-body" id="rpGroupBody">
|
|
251
|
+
<div class="group-list" id="groupList"></div>
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
|
|
256
|
+
<div id="rpHelperAgent"></div>
|
|
257
|
+
|
|
258
|
+
<div class="agent-panel-footer">
|
|
259
|
+
<button class="agent-collapse-btn" onclick="toggleAgentPanel()">
|
|
260
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 18 9 12 15 6"/></svg>
|
|
261
|
+
收起面板
|
|
262
|
+
</button>
|
|
263
|
+
</div>
|
|
264
|
+
</div>
|
|
16
265
|
|
|
17
|
-
<!-- Placeholder: Right Agents (loaded from right_agents.html) -->
|
|
18
|
-
<div id="rightAgentsContainer"></div>
|
|
19
266
|
</div>
|
|
20
267
|
|
|
21
268
|
<!-- Mobile Overlay -->
|
|
22
269
|
<div class="mobile-overlay" id="chatMobileOverlay"></div>
|
|
23
|
-
|
|
24
270
|
<!-- Toast Container -->
|
|
25
271
|
<div class="toast-container" id="toastContainer"></div>
|
|
26
|
-
|
|
27
272
|
<!-- Agent Modal Container -->
|
|
28
273
|
<div id="agentModalContainer"></div>
|
|
29
|
-
|
|
30
274
|
<!-- Group Modal Container -->
|
|
31
275
|
<div id="groupModalContainer"></div>
|
|
32
276
|
|
|
33
|
-
<!--
|
|
34
|
-
<script src="chat.js?v=
|
|
277
|
+
<!-- Load JS scripts (no HTML fragments to fetch) -->
|
|
278
|
+
<script src="chat.js?v=8"></script>
|
|
35
279
|
</body>
|
|
36
280
|
</html>
|
package/web/ui/index.html
CHANGED
|
@@ -542,7 +542,7 @@ async function openEditAgentModal(path){
|
|
|
542
542
|
<label class="btn btn-sm" style="cursor:pointer" ${isSys?'style=\"pointer-events:none;opacity:0.5\"':''}><input type="file" accept="image/*" hidden onchange="handleAvatarUpload(this,'ea')" ${isSys?'disabled':''}>
|
|
543
543
|
📷 上传图片
|
|
544
544
|
</label>
|
|
545
|
-
${a.avatar_image?'<button class="btn btn-sm btn-ghost" onclick="removeAvatarImage(
|
|
545
|
+
${a.avatar_image?'<button class="btn btn-sm btn-ghost" onclick="removeAvatarImage("'+escHtml(path)+'")">🗑️ 移除图片</button>':''}
|
|
546
546
|
</div>
|
|
547
547
|
<div id="eaCropArea" style="display:none;margin-top:8px">
|
|
548
548
|
<div style="position:relative;display:inline-block">
|