openclaw-openagent 1.0.13 → 1.0.14
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/dist/src/messaging/executor.d.ts +2 -3
- package/dist/src/messaging/executor.js +4 -31
- package/dist/src/plugin-ui/assets/openagent-override.js +4 -5
- package/dist/src/runtime/update-checker.d.ts +1 -1
- package/dist/src/runtime/update-checker.js +9 -46
- package/package.json +1 -3
- package/src/app/channel-tools.ts +0 -249
- package/src/app/discovery-tools.ts +0 -273
- package/src/app/download-file-tool.ts +0 -133
- package/src/app/hooks.ts +0 -144
- package/src/app/index.ts +0 -84
- package/src/app/messaging-tools.ts +0 -79
- package/src/app/ops-tools.ts +0 -155
- package/src/app/remote-agent-tool.ts +0 -762
- package/src/app/types.ts +0 -68
- package/src/app/upload-file-tool.ts +0 -411
- package/src/app/verbose-preflight.ts +0 -190
- package/src/auth/config.ts +0 -266
- package/src/auth/credential-manager.ts +0 -146
- package/src/auth/index.ts +0 -24
- package/src/auth/verify.ts +0 -99
- package/src/channel.ts +0 -566
- package/src/compat.ts +0 -94
- package/src/config/config-schema.ts +0 -45
- package/src/messaging/aggregator.ts +0 -120
- package/src/messaging/collector.ts +0 -89
- package/src/messaging/executor.ts +0 -72
- package/src/messaging/inbound.ts +0 -150
- package/src/messaging/index.ts +0 -11
- package/src/messaging/mention-protocol.ts +0 -94
- package/src/messaging/process-c2c-request.ts +0 -564
- package/src/messaging/process-message.ts +0 -373
- package/src/messaging/scheduler.ts +0 -55
- package/src/messaging/types.ts +0 -38
- package/src/plugin-ui/adapters/oc-2026-04.js +0 -103
- package/src/plugin-ui/adapters/oc-2026-05.js +0 -125
- package/src/plugin-ui/adapters/oc-2026-06.js +0 -125
- package/src/plugin-ui/adapters/oc-unknown.js +0 -48
- package/src/plugin-ui/assets/agentbook-icon.svg +0 -5
- package/src/plugin-ui/assets/bg.png +0 -0
- package/src/plugin-ui/assets/icon.png +0 -0
- package/src/plugin-ui/assets/magic.svg +0 -5
- package/src/plugin-ui/assets/openagent-override.js +0 -11263
- package/src/plugin-ui/build.cjs +0 -463
- package/src/plugin-ui/index.ts +0 -18
- package/src/plugin-ui/modules/agent-book/panel/agent-book.js +0 -570
- package/src/plugin-ui/modules/agent-book/panel/agent-card.js +0 -170
- package/src/plugin-ui/modules/agent-book/panel/agent-data.js +0 -643
- package/src/plugin-ui/modules/agent-book/panel/inject-ui.js +0 -665
- package/src/plugin-ui/modules/agent-book/panel/mention-state.js +0 -206
- package/src/plugin-ui/modules/agent-book/panel/styles.js +0 -832
- package/src/plugin-ui/modules/agent-book/panel/theme-adapter.js +0 -86
- package/src/plugin-ui/modules/agent-book/remote-agent-tool/components-core.js +0 -295
- package/src/plugin-ui/modules/agent-book/remote-agent-tool/thought-chain-card.js +0 -211
- package/src/plugin-ui/modules/agent-book/scanner.js +0 -131
- package/src/plugin-ui/modules/agent-book/travelcard/travel-cards.js +0 -500
- package/src/plugin-ui/modules/agent-book/travelcard/travel-engine.js +0 -652
- package/src/plugin-ui/modules/agent-book/travelcard/travel-styles.js +0 -262
- package/src/plugin-ui/modules/loader/bootstrap.js +0 -133
- package/src/plugin-ui/modules/loader/shared-state.js +0 -838
- package/src/plugin-ui/modules/loader/ws-intercept.js +0 -199
- package/src/plugin-ui/modules/remote-agent/chunk-parser.js +0 -161
- package/src/plugin-ui/modules/remote-agent/execution-card.js +0 -530
- package/src/plugin-ui/modules/remote-agent/markdown-renderer.js +0 -256
- package/src/plugin-ui/modules/remote-agent/media-links.js +0 -151
- package/src/plugin-ui/modules/remote-agent/native-style-adapter.js +0 -134
- package/src/plugin-ui/modules/remote-agent/output-card.js +0 -342
- package/src/plugin-ui/modules/remote-agent/progress-store.js +0 -363
- package/src/plugin-ui/modules/remote-agent/render-hooks.js +0 -1700
- package/src/plugin-ui/modules/remote-agent/styles.js +0 -903
- package/src/plugin-ui/modules/remote-agent/tool-card-model.js +0 -130
- package/src/plugin-ui/postinstall-deploy.cjs +0 -52
- package/src/plugin-ui/ui-extension-loader/backup.ts +0 -92
- package/src/plugin-ui/ui-extension-loader/index.ts +0 -276
- package/src/plugin-ui/ui-extension-loader/locator.ts +0 -152
- package/src/plugin-ui/ui-extension-loader/manifest.ts +0 -57
- package/src/plugin-ui/ui-extension-loader/registry-regex.ts +0 -944
- package/src/plugin-ui/ui-extension-loader/removed-extensions.ts +0 -70
- package/src/plugin-ui/ui-extension-loader/types.ts +0 -72
- package/src/proxy/auth-proxy.ts +0 -414
- package/src/runtime/account.ts +0 -549
- package/src/runtime/index.ts +0 -7
- package/src/runtime/plugin-runtime.ts +0 -94
- package/src/runtime/registry.ts +0 -71
- package/src/runtime/update-checker.ts +0 -286
- package/src/sdk/CLASS_MAP.md +0 -143
- package/src/sdk/index.d.ts +0 -126
- package/src/sdk/index.js +0 -23990
- package/src/sdk/modules/cloud-search-module.js +0 -1117
- package/src/sdk/modules/follow-module.js +0 -1069
- package/src/sdk/modules/group-module.js +0 -7397
- package/src/sdk/modules/relationship-module.js +0 -2269
- package/src/sdk/modules/signaling-module.js +0 -1468
- package/src/sdk/modules/tim-upload-plugin.js +0 -730
- package/src/sdk/node-env/http-request.js +0 -90
- package/src/sdk/node-env/index.js +0 -57
- package/src/sdk/node-env/storage.js +0 -114
- package/src/sdk/package.json +0 -10
- package/src/sdk/tsconfig.json +0 -16
- package/src/state/pending-invocation-store.ts +0 -43
- package/src/state/store.ts +0 -756
- package/src/tim/c2c.ts +0 -451
- package/src/tim/channels.ts +0 -364
- package/src/tim/client.ts +0 -330
- package/src/tim/index.ts +0 -18
- package/src/tim/messages.ts +0 -166
- package/src/tim/sdk-logger-init.ts +0 -50
- package/src/tools.ts +0 -10
- package/src/transport/factory.ts +0 -95
- package/src/transport/oasn/index.ts +0 -17
- package/src/transport/oasn/oasn-agent-card.ts +0 -111
- package/src/transport/oasn/oasn-discovery.ts +0 -108
- package/src/transport/oasn/oasn-files.ts +0 -210
- package/src/transport/oasn/oasn-http.ts +0 -529
- package/src/transport/oasn/oasn-invocation.ts +0 -604
- package/src/transport/oasn/oasn-normalize.ts +0 -133
- package/src/transport/oasn/oasn-register.ts +0 -33
- package/src/transport/oasn/oasn-transport.ts +0 -318
- package/src/transport/oasn/oasn-types.ts +0 -404
- package/src/transport/tim/index.ts +0 -8
- package/src/transport/tim/tim-transport.ts +0 -515
- package/src/transport/types.ts +0 -538
- package/src/types/openclaw-plugin-sdk-media-store.d.ts +0 -9
- package/src/types/openclaw.d.ts +0 -97
- package/src/types/tencentcloud-chat.d.ts +0 -15
- package/src/util/http.ts +0 -113
- package/src/util/logger.ts +0 -131
- package/src/util/url-resolver.ts +0 -77
|
@@ -1,570 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// ── UI 构建 ──
|
|
4
|
-
|
|
5
|
-
let panel = null;
|
|
6
|
-
let backdrop = null;
|
|
7
|
-
|
|
8
|
-
let inputWrapperRef = null; // 保存输入框包裹层引用
|
|
9
|
-
let panelPositionResizeObserver = null;
|
|
10
|
-
|
|
11
|
-
// ── 键盘导航状态(§1.5)──
|
|
12
|
-
// 对标 TIM index.ts:13 "let selectedIndex: number = 0"
|
|
13
|
-
let selectedIndex = 0;
|
|
14
|
-
let _currentAgents = []; // 当前列表中的 agents(供键盘选中使用)
|
|
15
|
-
let _currentTextarea = null; // 当前关联的 textarea
|
|
16
|
-
|
|
17
|
-
function ensurePanel() {
|
|
18
|
-
if (panel) return panel;
|
|
19
|
-
|
|
20
|
-
// 背景遮罩(点击关闭)
|
|
21
|
-
backdrop = document.createElement('div');
|
|
22
|
-
backdrop.className = 'openagent-panel-backdrop';
|
|
23
|
-
backdrop.addEventListener('click', () => {
|
|
24
|
-
console.log('[openagent] 🔲 backdrop clicked → closePanel (dismissed)');
|
|
25
|
-
// backdrop 关闭 = 用户主动关闭 → 触发 dismissed(同 ESC 意图)
|
|
26
|
-
setDismissed();
|
|
27
|
-
closePanel();
|
|
28
|
-
});
|
|
29
|
-
document.body.appendChild(backdrop);
|
|
30
|
-
|
|
31
|
-
// 全局点击诊断(捕获阶段,看最先点到什么)
|
|
32
|
-
document.addEventListener('click', (e) => {
|
|
33
|
-
if (panel && panel.classList.contains('visible')) {
|
|
34
|
-
console.log('[openagent] 🔍 global click capture:', e.target.tagName, e.target.className, 'composedPath[0]:', e.composedPath()[0]?.tagName);
|
|
35
|
-
}
|
|
36
|
-
}, true); // 捕获阶段
|
|
37
|
-
|
|
38
|
-
// 面板 — 独立浮动卡片
|
|
39
|
-
panel = document.createElement('div');
|
|
40
|
-
panel.className = 'openagent-agent-panel';
|
|
41
|
-
panel.innerHTML = `
|
|
42
|
-
<div class="openagent-panel-head">
|
|
43
|
-
<span class="openagent-panel-title">
|
|
44
|
-
<svg class="openagent-panel-title-icon" width="24" height="24" viewBox="0 0 56 56" fill="none">
|
|
45
|
-
<path d="M28 25H32C34.2091 25 36 26.7909 36 29V39C36 41.2091 34.2091 43 32 43H14C11.7909 43 10 41.2091 10 39V29C10 26.7909 11.7909 25 14 25H15" stroke="#12CCF6" stroke-width="3.3" stroke-linecap="round"/>
|
|
46
|
-
<path d="M39 31H42C44.2091 31 46 29.2091 46 27V17C46 14.7909 44.2091 13 42 13H24C21.7909 13 20 14.7909 20 17V27C20 29.2091 21.7909 31 24 31H30.0652C30.236 31 30.3282 31.2004 30.217 31.3302L27.5 34.5" stroke="#12CCF6" stroke-width="3.3" stroke-linecap="round"/>
|
|
47
|
-
<path d="M27 25.5L32.5 21" stroke="#12CCF6" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
|
48
|
-
</svg>
|
|
49
|
-
<span class="panel-title-text">OpenAgent</span>
|
|
50
|
-
</span>
|
|
51
|
-
<button class="openagent-panel-close"><svg xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 21 21" fill="none"><path d="M5.625 5.625L15.375 15.375" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M15.375 5.625L5.625 15.375" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
|
|
52
|
-
</div>
|
|
53
|
-
<hr class="openagent-panel-divider" />
|
|
54
|
-
<div class="openagent-agent-list">
|
|
55
|
-
<div class="openagent-loading">加载中...</div>
|
|
56
|
-
</div>
|
|
57
|
-
`;
|
|
58
|
-
panel.querySelector('.openagent-panel-close').addEventListener('click', () => {
|
|
59
|
-
// ✕ 按钮关闭 = 用户主动关闭 → 触发 dismissed(同 ESC 意图)
|
|
60
|
-
setDismissed();
|
|
61
|
-
closePanel();
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// 提示栏关闭按钮
|
|
66
|
-
const hintClose = panel.querySelector('.openagent-hint-bar__close');
|
|
67
|
-
if (hintClose) {
|
|
68
|
-
hintClose.addEventListener('click', () => {
|
|
69
|
-
const hintBar = panel.querySelector('.openagent-hint-bar');
|
|
70
|
-
if (hintBar) hintBar.style.display = 'none';
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
// 挂到 body(与 backdrop 同级,z-index 自然生效)
|
|
74
|
-
document.body.appendChild(panel);
|
|
75
|
-
return panel;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/** 根据 inputWrapper 位置动态定位 panel */
|
|
79
|
-
function _positionPanel() {
|
|
80
|
-
if (!panel || !inputWrapperRef) return;
|
|
81
|
-
const rect = inputWrapperRef.getBoundingClientRect();
|
|
82
|
-
const viewportPadding = 16;
|
|
83
|
-
const width = Math.min(rect.width, window.innerWidth - viewportPadding * 2);
|
|
84
|
-
const left = Math.max(viewportPadding, Math.min(rect.left, window.innerWidth - width - viewportPadding));
|
|
85
|
-
panel.style.left = left + 'px';
|
|
86
|
-
panel.style.width = width + 'px';
|
|
87
|
-
const toolbar = _findPanelToolbar();
|
|
88
|
-
const isComposerWrapper = inputWrapperRef.classList
|
|
89
|
-
&& inputWrapperRef.classList.contains('agent-chat__composer-combobox');
|
|
90
|
-
if (isComposerWrapper) {
|
|
91
|
-
panel.style.bottom = (_readElementHeight(inputWrapperRef) + _readElementHeight(toolbar) + 35) + 'px';
|
|
92
|
-
} else {
|
|
93
|
-
panel.style.bottom = (window.innerHeight - rect.top + 8) + 'px';
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/** resize 时实时跟随输入框 */
|
|
98
|
-
function _onResize() { _positionPanel(); }
|
|
99
|
-
|
|
100
|
-
function _findPanelToolbar() {
|
|
101
|
-
if (!inputWrapperRef) return null;
|
|
102
|
-
var chatInput = inputWrapperRef.closest && inputWrapperRef.closest('.agent-chat__input');
|
|
103
|
-
if (chatInput) {
|
|
104
|
-
var toolbar = chatInput.querySelector('.agent-chat__toolbar');
|
|
105
|
-
if (toolbar) return toolbar;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
var parentEl = inputWrapperRef.parentElement;
|
|
109
|
-
if (parentEl) {
|
|
110
|
-
for (var i = 0; i < parentEl.children.length; i++) {
|
|
111
|
-
var child = parentEl.children[i];
|
|
112
|
-
if (child !== inputWrapperRef && child.className && String(child.className).indexOf('agent-chat__toolbar') !== -1) {
|
|
113
|
-
return child;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function _readElementHeight(el) {
|
|
121
|
-
if (!el) return 0;
|
|
122
|
-
var rect = el.getBoundingClientRect ? el.getBoundingClientRect() : null;
|
|
123
|
-
if (rect && rect.height > 0) return rect.height;
|
|
124
|
-
return typeof el.offsetHeight === 'number' ? el.offsetHeight : 0;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function _schedulePanelPosition() {
|
|
128
|
-
window.requestAnimationFrame
|
|
129
|
-
? window.requestAnimationFrame(_positionPanel)
|
|
130
|
-
: setTimeout(_positionPanel, 0);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function _installPanelPositionObservers() {
|
|
134
|
-
if (panelPositionResizeObserver) {
|
|
135
|
-
panelPositionResizeObserver.disconnect();
|
|
136
|
-
panelPositionResizeObserver = null;
|
|
137
|
-
}
|
|
138
|
-
if (typeof ResizeObserver !== 'function' || !inputWrapperRef) return;
|
|
139
|
-
|
|
140
|
-
panelPositionResizeObserver = new ResizeObserver(_schedulePanelPosition);
|
|
141
|
-
panelPositionResizeObserver.observe(inputWrapperRef);
|
|
142
|
-
var toolbar = _findPanelToolbar();
|
|
143
|
-
if (toolbar) panelPositionResizeObserver.observe(toolbar);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function _teardownPanelPositionObservers() {
|
|
147
|
-
if (!panelPositionResizeObserver) return;
|
|
148
|
-
panelPositionResizeObserver.disconnect();
|
|
149
|
-
panelPositionResizeObserver = null;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// 搜索状态管理
|
|
153
|
-
let currentAbort = null; // AbortController for in-flight search
|
|
154
|
-
let searchDebounceId = null;
|
|
155
|
-
|
|
156
|
-
// ── @mention → systemProvenanceReceipt 状态 ──
|
|
157
|
-
// 当用户从 Agent Book 选中一个 agent 时,保存其 metadata。
|
|
158
|
-
// 下次 chat.send 时作为 systemProvenanceReceipt 注入,发送后清空。
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* 提取输入框文本作为搜索词(对齐 openagent-frontend NewChatPanel L82)
|
|
162
|
-
* 去掉所有 @ 符号,合并空白
|
|
163
|
-
*/
|
|
164
|
-
function extractSearchQuery(textarea) {
|
|
165
|
-
if (!textarea) return '';
|
|
166
|
-
return textarea.value.replace(/@/g, ' ').replace(/\s+/g, ' ').trim();
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function openPanel(textarea) {
|
|
170
|
-
// 清除上次的空状态弹窗
|
|
171
|
-
var oldToast = document.querySelector('.openagent-empty-toast');
|
|
172
|
-
if (oldToast) oldToast.remove();
|
|
173
|
-
var oldEmpty = document.querySelector('.openagent-empty-state');
|
|
174
|
-
if (oldEmpty) oldEmpty.remove();
|
|
175
|
-
|
|
176
|
-
const p = ensurePanel();
|
|
177
|
-
_positionPanel(); // 动态定位到 input 上方
|
|
178
|
-
_installPanelPositionObservers();
|
|
179
|
-
p.classList.add('visible');
|
|
180
|
-
backdrop.classList.add('visible');
|
|
181
|
-
window.addEventListener('resize', _onResize);
|
|
182
|
-
|
|
183
|
-
const list = p.querySelector('.openagent-agent-list');
|
|
184
|
-
list.innerHTML = '<div class="openagent-loading">加载中...</div>';
|
|
185
|
-
|
|
186
|
-
// 提取当前输入文本作为搜索词
|
|
187
|
-
const query = extractSearchQuery(textarea);
|
|
188
|
-
console.log('[openagent] openPanel with search query:', JSON.stringify(query));
|
|
189
|
-
|
|
190
|
-
if (query) {
|
|
191
|
-
// 有输入文本 → 语义搜索
|
|
192
|
-
searchAgents(query).then(agents => {
|
|
193
|
-
if (!p.classList.contains('visible')) return;
|
|
194
|
-
renderAgentList(list, agents, textarea, query);
|
|
195
|
-
});
|
|
196
|
-
} else {
|
|
197
|
-
// 空输入 → 全量列表
|
|
198
|
-
fetchAgentSections().then(agents => {
|
|
199
|
-
if (!p.classList.contains('visible')) return;
|
|
200
|
-
renderAgentList(list, agents, textarea, query);
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* 实时搜索更新(debounce 300ms,对齐 MentionPickerPopup)
|
|
206
|
-
* 当面板打开时,textarea 每次输入都会触发
|
|
207
|
-
*/
|
|
208
|
-
function updatePanelSearch(textarea) {
|
|
209
|
-
if (!panel || !panel.classList.contains('visible')) return;
|
|
210
|
-
|
|
211
|
-
// 取消前一个请求
|
|
212
|
-
if (currentAbort) currentAbort.abort();
|
|
213
|
-
if (searchDebounceId) clearTimeout(searchDebounceId);
|
|
214
|
-
|
|
215
|
-
const query = extractSearchQuery(textarea);
|
|
216
|
-
const list = panel.querySelector('.openagent-agent-list');
|
|
217
|
-
|
|
218
|
-
searchDebounceId = setTimeout(() => {
|
|
219
|
-
currentAbort = new AbortController();
|
|
220
|
-
const signal = currentAbort.signal;
|
|
221
|
-
|
|
222
|
-
list.innerHTML = '<div class="openagent-loading">搜索中...</div>';
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
const doSearch = query
|
|
226
|
-
? searchAgents(query, signal)
|
|
227
|
-
: fetchAgentSections();
|
|
228
|
-
|
|
229
|
-
doSearch.then(agents => {
|
|
230
|
-
if (signal.aborted) return;
|
|
231
|
-
if (!panel.classList.contains('visible')) return;
|
|
232
|
-
renderAgentList(list, agents, textarea, query);
|
|
233
|
-
});
|
|
234
|
-
}, 300);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
function closePanel() {
|
|
238
|
-
if (panel) panel.classList.remove('visible');
|
|
239
|
-
if (backdrop) backdrop.classList.remove('visible');
|
|
240
|
-
window.removeEventListener('resize', _onResize);
|
|
241
|
-
_teardownPanelPositionObservers();
|
|
242
|
-
// 清理搜索状态
|
|
243
|
-
if (currentAbort) { currentAbort.abort(); currentAbort = null; }
|
|
244
|
-
if (searchDebounceId) { clearTimeout(searchDebounceId); searchDebounceId = null; }
|
|
245
|
-
// 同步状态机(如果 dismissed 已由 setDismissed() 设置则不覆盖)
|
|
246
|
-
closeMention();
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// ── 键盘导航函数(§1.5)──
|
|
250
|
-
// 对标 TIM index.ts:158-173 upHandler/downHandler/enterHandler
|
|
251
|
-
|
|
252
|
-
function moveSelectionUp() {
|
|
253
|
-
const len = _currentAgents.length;
|
|
254
|
-
if (!len) return;
|
|
255
|
-
selectedIndex = (selectedIndex + len - 1) % len;
|
|
256
|
-
_highlightItem(selectedIndex);
|
|
257
|
-
_scrollItemIntoView(selectedIndex);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
function moveSelectionDown() {
|
|
261
|
-
const len = _currentAgents.length;
|
|
262
|
-
if (!len) return;
|
|
263
|
-
selectedIndex = (selectedIndex + 1) % len;
|
|
264
|
-
_highlightItem(selectedIndex);
|
|
265
|
-
_scrollItemIntoView(selectedIndex);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
function selectHighlightedAgent(textarea) {
|
|
269
|
-
const agent = _currentAgents[selectedIndex];
|
|
270
|
-
const ta = textarea || _currentTextarea;
|
|
271
|
-
if (agent && ta) {
|
|
272
|
-
insertMention(ta, agent.name, agent);
|
|
273
|
-
resetMention(); // 选中 Agent = 正常完成,清空一切(不触发 dismissed)
|
|
274
|
-
closePanel();
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
function _highlightItem(index) {
|
|
279
|
-
if (!panel) return;
|
|
280
|
-
const cards = panel.querySelectorAll('.openagent-agent-list .agent-card');
|
|
281
|
-
cards.forEach((c, i) => {
|
|
282
|
-
c.classList.toggle('openagent-card-selected', i === index);
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
function _scrollItemIntoView(index) {
|
|
287
|
-
if (!panel) return;
|
|
288
|
-
const cards = panel.querySelectorAll('.openagent-agent-list .agent-card');
|
|
289
|
-
if (cards[index]) {
|
|
290
|
-
cards[index].scrollIntoView({ block: 'nearest', behavior: 'smooth' });
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
function _appendParentSection(container, parentTitle, children, textarea, renderedAgents) {
|
|
295
|
-
const parentSec = _el('section', 'openagent-parent-section');
|
|
296
|
-
children.forEach(function(child) {
|
|
297
|
-
if (child.agents && child.agents.length > 0) {
|
|
298
|
-
_appendAgentSection(parentSec, child.title, child.agents, textarea, renderedAgents);
|
|
299
|
-
}
|
|
300
|
-
});
|
|
301
|
-
container.appendChild(parentSec);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
function _appendAgentSection(container, title, agents, textarea, renderedAgents) {
|
|
305
|
-
if (!agents.length) return;
|
|
306
|
-
const section = _el('section', 'openagent-agent-section');
|
|
307
|
-
section.appendChild(_text('div', 'openagent-section-heading', title));
|
|
308
|
-
|
|
309
|
-
const grid = _el('div', 'openagent-section-grid');
|
|
310
|
-
agents.forEach((a) => {
|
|
311
|
-
const displayIndex = renderedAgents.length;
|
|
312
|
-
const card = AgentCard(a, {
|
|
313
|
-
mode: 'mention',
|
|
314
|
-
onAction: () => {
|
|
315
|
-
console.log('[openagent] onAction fired for:', a.name);
|
|
316
|
-
insertMention(textarea, a.name, a);
|
|
317
|
-
resetMention(); // 点击选中 = 正常完成,清空一切
|
|
318
|
-
closePanel();
|
|
319
|
-
}
|
|
320
|
-
});
|
|
321
|
-
card.dataset.tag = a.tag || '';
|
|
322
|
-
card.dataset.name = a.name || '';
|
|
323
|
-
card.dataset.index = displayIndex;
|
|
324
|
-
grid.appendChild(card);
|
|
325
|
-
renderedAgents.push(a);
|
|
326
|
-
|
|
327
|
-
card.addEventListener('mousedown', () => console.log('[openagent] 🖱 mousedown on card:', a.name));
|
|
328
|
-
const tryBtn = card.querySelector('.agent-card__action');
|
|
329
|
-
if (tryBtn) {
|
|
330
|
-
tryBtn.addEventListener('mousedown', (e) => {
|
|
331
|
-
console.log('[openagent] 🖱 mousedown on Try btn:', a.name, 'target:', e.target.tagName, e.target.className);
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
section.appendChild(grid);
|
|
336
|
-
container.appendChild(section);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
function _appendSearchResults(container, agents, textarea, renderedAgents) {
|
|
340
|
-
const list = _el('div', 'openagent-search-results');
|
|
341
|
-
agents.forEach((a) => {
|
|
342
|
-
const displayIndex = renderedAgents.length;
|
|
343
|
-
const card = AgentCard(a, {
|
|
344
|
-
mode: 'search',
|
|
345
|
-
onAction: () => {
|
|
346
|
-
insertMention(textarea, a.name, a);
|
|
347
|
-
resetMention();
|
|
348
|
-
closePanel();
|
|
349
|
-
}
|
|
350
|
-
});
|
|
351
|
-
card.dataset.tag = a.tag || '';
|
|
352
|
-
card.dataset.name = a.name || '';
|
|
353
|
-
card.dataset.index = displayIndex;
|
|
354
|
-
list.appendChild(card);
|
|
355
|
-
renderedAgents.push(a);
|
|
356
|
-
});
|
|
357
|
-
container.appendChild(list);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* 空状态组件(Figma 144:3444)— 未匹配到 Agent 时显示
|
|
362
|
-
*/
|
|
363
|
-
/** 关闭已有空状态浮层 */
|
|
364
|
-
function _dismissEmptyToast() {
|
|
365
|
-
var existing = document.querySelector('.openagent-empty-toast');
|
|
366
|
-
if (existing) existing.remove();
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/** 独立浮层空状态(不在面板内) */
|
|
370
|
-
function _getEmptyMessage(query) {
|
|
371
|
-
return CL.agentBookLastError ||
|
|
372
|
-
(query ? '暂未匹配到您想要的Agent 我们将持续上新~' : '暂无在线 Agent,请输入关键词搜索');
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
function _showEmptyToast(query, message) {
|
|
376
|
-
_dismissEmptyToast();
|
|
377
|
-
var toast = _el('div', 'openagent-empty-toast');
|
|
378
|
-
|
|
379
|
-
var iconWrap = _el('div', 'openagent-empty-state__icon');
|
|
380
|
-
iconWrap.innerHTML = '<svg width="14" height="14" viewBox="0 0 14 14" fill="none">' +
|
|
381
|
-
'<path d="M7 1.5C10.0376 1.5 12.5 3.96243 12.5 7C12.5 8.69527 11.7389 10.2145 10.5237 11.2559L13.0303 13.7626C13.3232 14.0555 13.3232 14.5303 13.0303 14.8232C12.7374 15.1161 12.2626 15.1161 11.9697 14.8232L9.38402 12.2376C8.53401 12.7803 7.49507 13.1079 6.37793 13.1079L7 12.5C6.99363 12.5008 6.98726 12.5012 6.98089 12.5012C3.9368 12.5307 1.46927 10.0632 1.49878 7.01908C1.52829 3.97499 3.99398 1.50537 7.03789 1.5H7ZM7 3C4.79086 3 3 4.79086 3 7C3 9.20914 4.79086 11 7 11C9.20914 11 11 9.20914 11 7C11 4.79086 9.20914 3 7 3Z" fill="#8274ff" fill-opacity="0.6"/>' +
|
|
382
|
-
'</svg>';
|
|
383
|
-
toast.appendChild(iconWrap);
|
|
384
|
-
|
|
385
|
-
toast.appendChild(_text('span', 'openagent-empty-state__text', message || _getEmptyMessage(query)));
|
|
386
|
-
|
|
387
|
-
var closeBtn = _el('button', 'openagent-empty-state__close');
|
|
388
|
-
closeBtn.innerHTML = '<svg width="12" height="12" viewBox="0 0 12 12" fill="none">' +
|
|
389
|
-
'<path d="M1 1L11 11M11 1L1 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>' +
|
|
390
|
-
'</svg>';
|
|
391
|
-
closeBtn.addEventListener('click', function() { toast.remove(); });
|
|
392
|
-
toast.appendChild(closeBtn);
|
|
393
|
-
|
|
394
|
-
// 定位到输入框上方
|
|
395
|
-
if (inputWrapperRef) {
|
|
396
|
-
var rect = inputWrapperRef.getBoundingClientRect();
|
|
397
|
-
toast.style.position = 'fixed';
|
|
398
|
-
toast.style.left = Math.max(16, rect.left) + 'px';
|
|
399
|
-
toast.style.width = Math.min(rect.width, window.innerWidth - 32) + 'px';
|
|
400
|
-
toast.style.bottom = (window.innerHeight - rect.top + 8) + 'px';
|
|
401
|
-
// ── V2 版本兼容:v1 bottom 固定 117px ──
|
|
402
|
-
var isV2Toast = typeof _clIsHostVersionGte === 'function' && _clIsHostVersionGte('2026.6.9');
|
|
403
|
-
if (!isV2Toast) {
|
|
404
|
-
toast.style.bottom = '117px';
|
|
405
|
-
}
|
|
406
|
-
toast.style.zIndex = '100000';
|
|
407
|
-
}
|
|
408
|
-
document.body.appendChild(toast);
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
function _createEmptyState(query, message) {
|
|
412
|
-
var wrapper = _el('div', 'openagent-empty-state');
|
|
413
|
-
var row = _el('div', 'openagent-empty-state__row');
|
|
414
|
-
|
|
415
|
-
var iconWrap = _el('div', 'openagent-empty-state__icon');
|
|
416
|
-
iconWrap.innerHTML = '<svg width="14" height="14" viewBox="0 0 14 14" fill="none">' +
|
|
417
|
-
'<path d="M7 1.5C10.0376 1.5 12.5 3.96243 12.5 7C12.5 8.69527 11.7389 10.2145 10.5237 11.2559L13.0303 13.7626C13.3232 14.0555 13.3232 14.5303 13.0303 14.8232C12.7374 15.1161 12.2626 15.1161 11.9697 14.8232L9.38402 12.2376C8.53401 12.7803 7.49507 13.1079 6.37793 13.1079L7 12.5C6.99363 12.5008 6.98726 12.5012 6.98089 12.5012C3.9368 12.5307 1.46927 10.0632 1.49878 7.01908C1.52829 3.97499 3.99398 1.50537 7.03789 1.5H7ZM7 3C4.79086 3 3 4.79086 3 7C3 9.20914 4.79086 11 7 11C9.20914 11 11 9.20914 11 7C11 4.79086 9.20914 3 7 3Z" fill="#8274ff" fill-opacity="0.6"/>' +
|
|
418
|
-
'</svg>';
|
|
419
|
-
row.appendChild(iconWrap);
|
|
420
|
-
|
|
421
|
-
var text = _text('span', 'openagent-empty-state__text', message || _getEmptyMessage(query));
|
|
422
|
-
row.appendChild(text);
|
|
423
|
-
|
|
424
|
-
var closeBtn = _el('button', 'openagent-empty-state__close');
|
|
425
|
-
closeBtn.innerHTML = '<svg width="12" height="12" viewBox="0 0 12 12" fill="none">' +
|
|
426
|
-
'<path d="M1 1L11 11M11 1L1 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>' +
|
|
427
|
-
'</svg>';
|
|
428
|
-
closeBtn.addEventListener('click', function() {
|
|
429
|
-
wrapper.style.display = 'none';
|
|
430
|
-
});
|
|
431
|
-
row.appendChild(closeBtn);
|
|
432
|
-
|
|
433
|
-
wrapper.appendChild(row);
|
|
434
|
-
return wrapper;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
function renderAgentList(container, agents, textarea, query) {
|
|
438
|
-
if (!agents.length) {
|
|
439
|
-
var emptyMessage = _getEmptyMessage(query);
|
|
440
|
-
_currentAgents = [];
|
|
441
|
-
_currentTextarea = textarea;
|
|
442
|
-
closePanel();
|
|
443
|
-
_showEmptyToast(query, emptyMessage);
|
|
444
|
-
return;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
console.log('[openagent] renderAgentList:', agents.length, 'agents, textarea:', !!textarea);
|
|
448
|
-
|
|
449
|
-
container.innerHTML = '';
|
|
450
|
-
_currentTextarea = textarea;
|
|
451
|
-
|
|
452
|
-
const renderedAgents = [];
|
|
453
|
-
const normalizedQuery = (query || '').trim();
|
|
454
|
-
if (normalizedQuery) {
|
|
455
|
-
_appendSearchResults(container, agents, textarea, renderedAgents);
|
|
456
|
-
} else {
|
|
457
|
-
agents.forEach(section => {
|
|
458
|
-
if (section.children && section.children.length > 0) {
|
|
459
|
-
_appendParentSection(container, section.title, section.children, textarea, renderedAgents);
|
|
460
|
-
} else {
|
|
461
|
-
_appendAgentSection(container, section.title, section.agents || [], textarea, renderedAgents);
|
|
462
|
-
}
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
// 保存 DOM 顺序中的 agents 列表,供键盘导航使用
|
|
467
|
-
_currentAgents = renderedAgents;
|
|
468
|
-
|
|
469
|
-
// 默认高亮第一项(§1.5 默认选中)
|
|
470
|
-
// 对标 TIM index.ts:13 "selectedIndex = 0" + index.vue:32 ":class=[index===selectedIndex&&'selected']"
|
|
471
|
-
selectedIndex = 0;
|
|
472
|
-
_highlightItem(0);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
/**
|
|
476
|
-
* 选中 Agent 后插入 @name 到 textarea
|
|
477
|
-
* 对齐 openagent-frontend NewChatPanel L92-105:
|
|
478
|
-
* 找到最后一个 @,替换其后内容为 @agentName
|
|
479
|
-
*/
|
|
480
|
-
function _pickMentionAgentDescription(agent) {
|
|
481
|
-
if (!agent || typeof agent !== 'object') return '';
|
|
482
|
-
if (CL && typeof CL.pickAgentIdentityDescription === 'function') {
|
|
483
|
-
return CL.pickAgentIdentityDescription(agent);
|
|
484
|
-
}
|
|
485
|
-
const keys = ['agent_bio', 'agentBio', 'bio', 'description', 'desc', 'agent_description', 'agentDescription', 'MOM', 'mom'];
|
|
486
|
-
for (let i = 0; i < keys.length; i++) {
|
|
487
|
-
const value = agent[keys[i]];
|
|
488
|
-
if (typeof value === 'string' && value.trim()) return value.trim();
|
|
489
|
-
}
|
|
490
|
-
return '';
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
function insertMention(textarea, agentName, agentData) {
|
|
494
|
-
// 重新查找 textarea(Lit 可能重新渲染导致引用失效)
|
|
495
|
-
const liveTextarea = document.querySelector(
|
|
496
|
-
'textarea[placeholder*="Message"]'
|
|
497
|
-
) || document.querySelector(
|
|
498
|
-
'textarea[placeholder*="Enter to send"]'
|
|
499
|
-
) || textarea;
|
|
500
|
-
|
|
501
|
-
console.log('[openagent] insertMention:', agentName,
|
|
502
|
-
'textarea found:', !!liveTextarea,
|
|
503
|
-
'same ref:', liveTextarea === textarea);
|
|
504
|
-
|
|
505
|
-
if (!liveTextarea) return;
|
|
506
|
-
liveTextarea.focus();
|
|
507
|
-
|
|
508
|
-
// 存储 agent 信息,发送时替换为 {openagent:...} 标记
|
|
509
|
-
const agentId = agentData?.agent_id || agentData?.agentId || agentData?.id || agentData?.tag ||
|
|
510
|
-
agentData?.user_id || agentData?.userId || agentData?.identifier || agentData?.tim_user_id || agentData?.timUserId || '';
|
|
511
|
-
const agentAvatar = agentData?.avatar || agentData?.avatar_url || agentData?.avatarUrl || agentData?.image || agentData?.logo || agentData?.photo || null;
|
|
512
|
-
const agentBio = _pickMentionAgentDescription(agentData);
|
|
513
|
-
console.log('[cl-diag][mention-select]', {
|
|
514
|
-
agentName,
|
|
515
|
-
resolvedAgentId: agentId || null,
|
|
516
|
-
hasAgentBio: !!agentBio,
|
|
517
|
-
rawKeys: Object.keys(agentData || {}),
|
|
518
|
-
rawAgent: agentData,
|
|
519
|
-
});
|
|
520
|
-
if (!agentId) {
|
|
521
|
-
CL.pendingMention = null;
|
|
522
|
-
console.warn('[openagent] mention skipped: missing agent identifier for', agentName, agentData);
|
|
523
|
-
return;
|
|
524
|
-
}
|
|
525
|
-
CL.pendingMention = { agent_id: agentId, name: agentName, avatar: agentAvatar, agent_bio: agentBio };
|
|
526
|
-
if (CL && typeof CL.storeAgentIdentity === 'function') {
|
|
527
|
-
CL.storeAgentIdentity(Object.assign({}, agentData || {}, {
|
|
528
|
-
agent_id: agentId,
|
|
529
|
-
name: agentName,
|
|
530
|
-
avatar: agentAvatar,
|
|
531
|
-
agent_bio: agentBio,
|
|
532
|
-
}));
|
|
533
|
-
}
|
|
534
|
-
console.log('[openagent] mention stored:', CL.pendingMention);
|
|
535
|
-
|
|
536
|
-
// textarea 显示 @agentName(用户友好)
|
|
537
|
-
const val = liveTextarea.value;
|
|
538
|
-
const lastAtIndex = val.lastIndexOf('@');
|
|
539
|
-
let newValue;
|
|
540
|
-
if (lastAtIndex !== -1) {
|
|
541
|
-
const before = val.slice(0, lastAtIndex).trimEnd();
|
|
542
|
-
newValue = before ? `${before} @${agentName} ` : `@${agentName} `;
|
|
543
|
-
} else {
|
|
544
|
-
newValue = `${val}@${agentName} `;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
// 设置值
|
|
548
|
-
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
|
|
549
|
-
HTMLTextAreaElement.prototype, 'value'
|
|
550
|
-
)?.set;
|
|
551
|
-
if (nativeInputValueSetter) {
|
|
552
|
-
nativeInputValueSetter.call(liveTextarea, newValue);
|
|
553
|
-
} else {
|
|
554
|
-
liveTextarea.value = newValue;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
// 光标到末尾
|
|
558
|
-
liveTextarea.selectionStart = liveTextarea.selectionEnd = newValue.length;
|
|
559
|
-
|
|
560
|
-
// 触发事件让 Lit 识别变化
|
|
561
|
-
liveTextarea.dispatchEvent(new Event('input', { bubbles: true }));
|
|
562
|
-
liveTextarea.dispatchEvent(new Event('change', { bubbles: true }));
|
|
563
|
-
|
|
564
|
-
// 标记替换由 window.__clMention.onKeyDown 在 OC 注入钩子中处理
|
|
565
|
-
// 不再需要独立的 _installSendInterceptor
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
// _installSendInterceptor 已移除(v3)
|
|
569
|
-
// 标记替换逻辑迁移到 inject-ui.js → window.__clMention.onKeyDown
|
|
570
|
-
// 在 OC 的 handleKeyDown 钩子中执行,优先级在 slash menu 之后、Enter 发送之前
|