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,86 +0,0 @@
|
|
|
1
|
-
// ── OpenAgent Theme Adapter ──
|
|
2
|
-
//
|
|
3
|
-
// 运行时检测 OpenClaw Control UI 主题系统(v4.x vscode tokens / v5.x glassmorphism),
|
|
4
|
-
// 注入 --oa-* CSS 变量供 styles.js 中的 var() fallback 消费。
|
|
5
|
-
//
|
|
6
|
-
// 必须早于 styles.js 加载(由 build.cjs MANIFEST 顺序保证)。
|
|
7
|
-
|
|
8
|
-
(function _clInitThemeAdapter() {
|
|
9
|
-
if (window.__openagentThemeAdapterInstalled) return;
|
|
10
|
-
window.__openagentThemeAdapterInstalled = true;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* 检测当前 OC 主题系统类型。
|
|
14
|
-
* @returns {{ hasGlass: boolean, hasVscode: boolean, isDark: boolean }}
|
|
15
|
-
*/
|
|
16
|
-
function detectThemeSystem() {
|
|
17
|
-
var cs = getComputedStyle(document.documentElement);
|
|
18
|
-
var hasGlass = !!(cs.getPropertyValue('--glass-surface').trim());
|
|
19
|
-
var hasKn = !!(cs.getPropertyValue('--kn-bg-primary').trim());
|
|
20
|
-
var hasVscode = !!(cs.getPropertyValue('--vscode-editor-background').trim());
|
|
21
|
-
|
|
22
|
-
// 多策略暗色检测:v4 data-theme-mode / v5 data-theme / prefers-color-scheme
|
|
23
|
-
var themeMode = document.documentElement.getAttribute('data-theme-mode') // v4.x
|
|
24
|
-
|| document.documentElement.getAttribute('data-theme') // v5.x
|
|
25
|
-
|| '';
|
|
26
|
-
var isDark = themeMode.indexOf('dark') >= 0
|
|
27
|
-
|| window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
28
|
-
|
|
29
|
-
return {
|
|
30
|
-
hasGlass: hasGlass || hasKn,
|
|
31
|
-
hasVscode: hasVscode,
|
|
32
|
-
isDark: isDark
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* 注入 --oa-* CSS 变量到 :root。
|
|
38
|
-
* styles.js 中的 var(--oa-xxx, fallback) 会优先取这些值。
|
|
39
|
-
*/
|
|
40
|
-
function setupThemeVariables() {
|
|
41
|
-
var system = detectThemeSystem();
|
|
42
|
-
var root = document.documentElement;
|
|
43
|
-
|
|
44
|
-
if (system.hasGlass) {
|
|
45
|
-
// v5.x Glassmorphism: 使用 --glass-* / --kn-* token 族
|
|
46
|
-
root.style.setProperty('--oa-panel-bg', 'var(--glass-surface, var(--card))');
|
|
47
|
-
root.style.setProperty('--oa-panel-text', 'var(--kn-text-primary, var(--text, #e0e0e0))');
|
|
48
|
-
root.style.setProperty('--oa-card-bg', 'var(--glass-card, var(--card, #f5f5f5))');
|
|
49
|
-
root.style.setProperty('--oa-card-hover-bg', 'var(--glass-card-hover, var(--card-hover))');
|
|
50
|
-
root.style.setProperty('--oa-border', 'var(--glass-border, var(--border, #e5e5e5))');
|
|
51
|
-
root.style.setProperty('--oa-shadow-color', 'rgba(0, 0, 0, 0.08)');
|
|
52
|
-
root.style.setProperty('--oa-divider', 'var(--glass-divider, var(--border, #eee))');
|
|
53
|
-
root.style.setProperty('--oa-muted-text', 'var(--kn-text-secondary, var(--text-secondary, #999))');
|
|
54
|
-
} else if (system.hasVscode) {
|
|
55
|
-
// v4.x VSCode tokens: 使用 --vscode-* 变量
|
|
56
|
-
root.style.setProperty('--oa-panel-bg', 'var(--vscode-editor-background, #fff)');
|
|
57
|
-
root.style.setProperty('--oa-panel-text', 'var(--vscode-editor-foreground, #2F2F33)');
|
|
58
|
-
root.style.setProperty('--oa-card-bg', 'var(--vscode-sideBar-background, #f5f5f5)');
|
|
59
|
-
root.style.setProperty('--oa-card-hover-bg', 'var(--vscode-list-hoverBackground, #f0f0f0)');
|
|
60
|
-
root.style.setProperty('--oa-border', 'var(--vscode-panel-border, #e5e5e5)');
|
|
61
|
-
root.style.setProperty('--oa-shadow-color', 'rgba(0, 0, 0, 0.10)');
|
|
62
|
-
root.style.setProperty('--oa-divider', 'var(--vscode-sideBar-border, #eee)');
|
|
63
|
-
root.style.setProperty('--oa-muted-text', 'var(--vscode-descriptionForeground, #999)');
|
|
64
|
-
}
|
|
65
|
-
// 无特征 → 不注入变量,styles.js 中的 var() 会 fallback 到硬编码值
|
|
66
|
-
|
|
67
|
-
// 注入暗色 class 标记供 styles.js 选择器使用
|
|
68
|
-
if (system.isDark) {
|
|
69
|
-
root.style.setProperty('--oa-is-dark', '1');
|
|
70
|
-
} else {
|
|
71
|
-
root.style.setProperty('--oa-is-dark', '0');
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// 立即执行 + 监听主题变更(v5.x 可能运行时切换主题)
|
|
76
|
-
setupThemeVariables();
|
|
77
|
-
|
|
78
|
-
// 监听 data-theme / data-theme-mode 属性变更
|
|
79
|
-
var themeObserver = new MutationObserver(function () {
|
|
80
|
-
setupThemeVariables();
|
|
81
|
-
});
|
|
82
|
-
themeObserver.observe(document.documentElement, {
|
|
83
|
-
attributes: true,
|
|
84
|
-
attributeFilter: ['data-theme', 'data-theme-mode', 'class']
|
|
85
|
-
});
|
|
86
|
-
})();
|
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
// ── Agent Card 内嵌卡片 ──
|
|
2
|
-
|
|
3
|
-
/** 通过 agent_id / name / query 获取单个 Agent 详情 */
|
|
4
|
-
async function fetchAgentById(identifier, fallbackName) {
|
|
5
|
-
const keys = [];
|
|
6
|
-
const pushKey = (value) => {
|
|
7
|
-
const key = String(value || '').trim();
|
|
8
|
-
if (key && !keys.includes(key)) keys.push(key);
|
|
9
|
-
};
|
|
10
|
-
pushKey(identifier);
|
|
11
|
-
pushKey(fallbackName);
|
|
12
|
-
|
|
13
|
-
// 1. 先从缓存精确匹配
|
|
14
|
-
const identity = CL && typeof CL.getAgentIdentity === 'function'
|
|
15
|
-
? CL.getAgentIdentity(identifier, fallbackName)
|
|
16
|
-
: null;
|
|
17
|
-
if (identity) return identity;
|
|
18
|
-
|
|
19
|
-
const cached = CL.agentCache.find(a =>
|
|
20
|
-
keys.includes(a.id) || keys.includes(a.tag) || keys.includes(a.name)
|
|
21
|
-
);
|
|
22
|
-
if (cached) return cached;
|
|
23
|
-
|
|
24
|
-
// 2. 用列表 API 加载全量数据(如果缓存为空),按 UUID / 名字精确匹配
|
|
25
|
-
try {
|
|
26
|
-
const agents = await fetchAgents(); // 会更新 agentCache
|
|
27
|
-
const exact = agents.find(a =>
|
|
28
|
-
keys.includes(a.id) || keys.includes(a.tag) || keys.includes(a.name)
|
|
29
|
-
);
|
|
30
|
-
if (exact) return exact;
|
|
31
|
-
} catch (err) {
|
|
32
|
-
console.warn('[openagent] fetchAgentById list error:', err);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// 3. 精确匹配失败 → 逐个关键词搜索。当前后端不支持 UUID 语义搜索时,
|
|
36
|
-
// fallbackName 仍能命中真实 Agent,从而拿到 avatar 等展示字段。
|
|
37
|
-
for (let i = 0; i < keys.length; i++) {
|
|
38
|
-
const key = keys[i];
|
|
39
|
-
try {
|
|
40
|
-
const res = await fetch(`${SEARCH_API}?q=${encodeURIComponent(key)}&top_k=5`);
|
|
41
|
-
if (!res.ok) continue;
|
|
42
|
-
const data = await res.json();
|
|
43
|
-
const list = (data.results || []).map(mapAgent);
|
|
44
|
-
const exact = list.find(a =>
|
|
45
|
-
keys.includes(a.id) || keys.includes(a.tag) || keys.includes(a.name)
|
|
46
|
-
);
|
|
47
|
-
if (exact) {
|
|
48
|
-
if (CL && typeof CL.storeAgentIdentity === 'function') CL.storeAgentIdentity(exact);
|
|
49
|
-
return exact;
|
|
50
|
-
}
|
|
51
|
-
if (list[0]) {
|
|
52
|
-
if (CL && typeof CL.storeAgentIdentity === 'function') CL.storeAgentIdentity(list[0]);
|
|
53
|
-
return list[0];
|
|
54
|
-
}
|
|
55
|
-
} catch (err) {
|
|
56
|
-
console.warn('[openagent] fetchAgentById search error:', err);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** 构建 Agent 卡片 DOM(使用统一 AgentCard 组件) */
|
|
63
|
-
function buildAgentCard(agent) {
|
|
64
|
-
return AgentCard(agent, {
|
|
65
|
-
mode: 'inline',
|
|
66
|
-
onAction: (a) => {
|
|
67
|
-
const textarea = document.querySelector('.agent-chat__input textarea');
|
|
68
|
-
if (textarea) {
|
|
69
|
-
const current = textarea.value;
|
|
70
|
-
textarea.value = current + (current && !current.endsWith(' ') ? ' ' : '') + `@${a.name} `;
|
|
71
|
-
textarea.focus();
|
|
72
|
-
textarea.dispatchEvent(new Event('input', { bubbles: true }));
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// ── 组件注册表 ──
|
|
79
|
-
|
|
80
|
-
const OPENAGENT_COMPONENTS = {};
|
|
81
|
-
|
|
82
|
-
/** 注册一个自定义组件类型 */
|
|
83
|
-
function registerComponent(type, handler) {
|
|
84
|
-
OPENAGENT_COMPONENTS[type] = handler;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// 注册:Agent Card
|
|
88
|
-
registerComponent('agent-card', async (data) => {
|
|
89
|
-
const searchTerm = data.agent_id || data.agentId || data.id || data.name || data.query;
|
|
90
|
-
if (!searchTerm) return null;
|
|
91
|
-
const agent = await fetchAgentById(searchTerm);
|
|
92
|
-
return agent ? buildAgentCard(agent) : null;
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
// ── 组件协议:[[type:{...}]] 和 [[trip-data:...]] ──
|
|
96
|
-
//
|
|
97
|
-
// 不再使用宿主 marked.js 扩展。统一使用 DOM 文本扫描:
|
|
98
|
-
// [[agent-card:{"name":"..."}]] → 替换为 Agent Card 组件
|
|
99
|
-
// [[trip-data:file]] → 触发 trip card 数据加载
|
|
100
|
-
// [[trip-data:<base64>]] → 内联 trip card 数据注入
|
|
101
|
-
|
|
102
|
-
/** 处理 [[trip-data:...]] 文本协议 */
|
|
103
|
-
function _clHandleTripDataSignal(payload, contextNode) {
|
|
104
|
-
if (!payload) return;
|
|
105
|
-
console.log('[trip-data] detected signal, payload:', payload.substring(0, 40));
|
|
106
|
-
const hostTextContextSelector = (typeof CL !== 'undefined' && CL.hostAdapter && CL.hostAdapter.selectors && CL.hostAdapter.selectors.textContext)
|
|
107
|
-
|| '.chat-text';
|
|
108
|
-
|
|
109
|
-
if (payload === 'file') {
|
|
110
|
-
const chatText = contextNode && contextNode.closest
|
|
111
|
-
? contextNode.closest(hostTextContextSelector)
|
|
112
|
-
: null;
|
|
113
|
-
if (chatText) {
|
|
114
|
-
chatText.dataset.clProcessed = '';
|
|
115
|
-
if (typeof _processCustomCards === 'function') _processCustomCards(chatText);
|
|
116
|
-
}
|
|
117
|
-
} else {
|
|
118
|
-
// base64 payload
|
|
119
|
-
try {
|
|
120
|
-
const cardData = JSON.parse(atob(payload));
|
|
121
|
-
if (typeof CL !== 'undefined' && typeof CL.mergeTripCardData === 'function') {
|
|
122
|
-
CL.mergeTripCardData(cardData, { replaceDayList: true });
|
|
123
|
-
} else if (typeof CL !== 'undefined') {
|
|
124
|
-
CL.tripCardData = cardData;
|
|
125
|
-
}
|
|
126
|
-
console.log('[trip-data] ✅ Card data from base64');
|
|
127
|
-
const chatText = contextNode && contextNode.closest
|
|
128
|
-
? contextNode.closest(hostTextContextSelector)
|
|
129
|
-
: null;
|
|
130
|
-
if (chatText) {
|
|
131
|
-
chatText.dataset.clProcessed = '';
|
|
132
|
-
if (typeof _processCustomCards === 'function') _processCustomCards(chatText);
|
|
133
|
-
}
|
|
134
|
-
} catch (e) {
|
|
135
|
-
console.warn('[trip-data] ❌ base64 decode failed:', e && e.message);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/** 扫描 DOM 中的组件占位(纯文本扫描,不依赖 marked) */
|
|
141
|
-
function scanForComponents(root) {
|
|
142
|
-
if (!root) return;
|
|
143
|
-
scanTextNodesForComponents(root);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/** DOM 文本扫描降级方案 */
|
|
147
|
-
function scanTextNodesForComponents(root) {
|
|
148
|
-
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null);
|
|
149
|
-
const matchedNodes = [];
|
|
150
|
-
let node;
|
|
151
|
-
while (node = walker.nextNode()) {
|
|
152
|
-
if (node.textContent.includes('[[') && node.textContent.includes(']]')) {
|
|
153
|
-
if (node.parentElement?.dataset?.openagentProcessed) continue;
|
|
154
|
-
matchedNodes.push(node);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
matchedNodes.forEach(replaceComponentTextNode);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/** 替换文本节点中的 [[type:{...}]] 或处理 [[trip-data:...]] */
|
|
161
|
-
function replaceComponentTextNode(textNode) {
|
|
162
|
-
const text = textNode.textContent;
|
|
163
|
-
const match = /\[\[([\w][\w-]*):(.*?)\]\]/.exec(text);
|
|
164
|
-
if (!match) return;
|
|
165
|
-
|
|
166
|
-
const type = match[1];
|
|
167
|
-
|
|
168
|
-
// ── trip-data 信号:不替换 DOM,直接处理数据 ──
|
|
169
|
-
if (type === 'trip-data') {
|
|
170
|
-
_clHandleTripDataSignal(match[2].trim(), textNode);
|
|
171
|
-
// 隐藏信号文本
|
|
172
|
-
const parentEl = textNode.parentElement;
|
|
173
|
-
if (parentEl) parentEl.style.display = 'none';
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const handler = OPENAGENT_COMPONENTS[type];
|
|
178
|
-
if (!handler) return;
|
|
179
|
-
|
|
180
|
-
let data;
|
|
181
|
-
try {
|
|
182
|
-
data = JSON.parse(match[2].trim());
|
|
183
|
-
} catch {
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const parentEl = textNode.parentElement;
|
|
188
|
-
if (!parentEl) return;
|
|
189
|
-
parentEl.dataset.openagentProcessed = 'true';
|
|
190
|
-
|
|
191
|
-
const before = text.substring(0, match.index);
|
|
192
|
-
const after = text.substring(match.index + match[0].length);
|
|
193
|
-
const fragment = document.createDocumentFragment();
|
|
194
|
-
if (before.trim()) fragment.appendChild(document.createTextNode(before));
|
|
195
|
-
|
|
196
|
-
const placeholder = document.createElement('div');
|
|
197
|
-
placeholder.className = 'agent-card__loading';
|
|
198
|
-
placeholder.textContent = '🔍 Loading...';
|
|
199
|
-
fragment.appendChild(placeholder);
|
|
200
|
-
|
|
201
|
-
if (after.trim()) fragment.appendChild(document.createTextNode(after));
|
|
202
|
-
parentEl.replaceChild(fragment, textNode);
|
|
203
|
-
|
|
204
|
-
handler(data).then(component => {
|
|
205
|
-
if (component) {
|
|
206
|
-
placeholder.replaceWith(component);
|
|
207
|
-
} else {
|
|
208
|
-
placeholder.textContent = `⚠️ Component "${type}" load failed`;
|
|
209
|
-
}
|
|
210
|
-
}).catch(err => {
|
|
211
|
-
console.warn(`[openagent] Component "${type}" handler error:`, err);
|
|
212
|
-
placeholder.textContent = `⚠️ Component "${type}" error`;
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// ── 组件 Observer ──
|
|
217
|
-
|
|
218
|
-
function startComponentObserver() {
|
|
219
|
-
const chatThread = document.querySelector('.chat-thread');
|
|
220
|
-
if (!chatThread) return;
|
|
221
|
-
|
|
222
|
-
// 先扫描已有的
|
|
223
|
-
scanForComponents(chatThread);
|
|
224
|
-
|
|
225
|
-
const observer = new MutationObserver(() => {
|
|
226
|
-
scanForComponents(chatThread);
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
observer.observe(chatThread, { childList: true, subtree: true });
|
|
230
|
-
|
|
231
|
-
// 周期扫描兜底(DOM mutation 可能漏掉某些 SPA 渲染)
|
|
232
|
-
setInterval(() => {
|
|
233
|
-
const thread = document.querySelector('.chat-thread');
|
|
234
|
-
if (thread) scanForComponents(thread);
|
|
235
|
-
}, 1500);
|
|
236
|
-
console.log('[openagent] ✅ Component observer started (text scan mode)');
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// ── 启动(需要 DOM 就绪) ──
|
|
240
|
-
|
|
241
|
-
function bootstrap() {
|
|
242
|
-
injectStyles();
|
|
243
|
-
|
|
244
|
-
// 初次加载轮询(兼容 textarea 延迟渲染)
|
|
245
|
-
let attempts = 0;
|
|
246
|
-
const pollTimer = setInterval(() => {
|
|
247
|
-
attempts++;
|
|
248
|
-
if (tryInject() || attempts >= CL.MAX_POLL) {
|
|
249
|
-
clearInterval(pollTimer);
|
|
250
|
-
if (attempts >= CL.MAX_POLL) {
|
|
251
|
-
console.warn('[openagent] ⚠️ textarea not found after', CL.MAX_POLL, 'attempts, observer will keep watching');
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}, CL.POLL_INTERVAL);
|
|
255
|
-
|
|
256
|
-
// 持续监听 DOM 变化:无论路由切换、SPA 重渲染、还是延迟加载,
|
|
257
|
-
// 只要 textarea 出现且未注入,就自动注入 Agent Book
|
|
258
|
-
let _injectDebounce = null;
|
|
259
|
-
const routeObserver = new MutationObserver(() => {
|
|
260
|
-
// debounce 300ms 避免高频触发
|
|
261
|
-
if (_injectDebounce) clearTimeout(_injectDebounce);
|
|
262
|
-
_injectDebounce = setTimeout(() => {
|
|
263
|
-
// 如果还没注入成功,持续尝试
|
|
264
|
-
if (!document.querySelector('.openagent-at-btn')) {
|
|
265
|
-
tryInject();
|
|
266
|
-
}
|
|
267
|
-
// 检查是否需要启动 component observer
|
|
268
|
-
const thread = document.querySelector('.chat-thread');
|
|
269
|
-
if (thread && !thread._openagentCompObs) {
|
|
270
|
-
thread._openagentCompObs = true;
|
|
271
|
-
startComponentObserver();
|
|
272
|
-
}
|
|
273
|
-
}, 300);
|
|
274
|
-
});
|
|
275
|
-
if (document.body) {
|
|
276
|
-
routeObserver.observe(document.body, { childList: true, subtree: true });
|
|
277
|
-
} else {
|
|
278
|
-
const bodyWaiter = setInterval(() => {
|
|
279
|
-
if (document.body) {
|
|
280
|
-
clearInterval(bodyWaiter);
|
|
281
|
-
routeObserver.observe(document.body, { childList: true, subtree: true });
|
|
282
|
-
}
|
|
283
|
-
}, 100);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// 首次启动 component observer
|
|
287
|
-
setTimeout(() => startComponentObserver(), 2000);
|
|
288
|
-
} // end bootstrap()
|
|
289
|
-
|
|
290
|
-
// 等 DOM 就绪后再执行 bootstrap
|
|
291
|
-
if (document.readyState === 'loading') {
|
|
292
|
-
document.addEventListener('DOMContentLoaded', bootstrap);
|
|
293
|
-
} else {
|
|
294
|
-
bootstrap();
|
|
295
|
-
}
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
// ── Shared remote-agent visual primitives ───────────────────────────────
|
|
2
|
-
//
|
|
3
|
-
// Remote-agent ToolCard rendering is owned by remote-agent/render-hooks.js.
|
|
4
|
-
// This module keeps the shared styles/helpers and forwards WS events only.
|
|
5
|
-
|
|
6
|
-
// ── 1. CSS 注入 ──
|
|
7
|
-
|
|
8
|
-
(function injectThoughtChainStyles() {
|
|
9
|
-
var oldStyle = document.getElementById('cl-tools-collapse-css');
|
|
10
|
-
if (oldStyle) oldStyle.remove();
|
|
11
|
-
const style = document.createElement('style');
|
|
12
|
-
style.id = 'cl-tools-collapse-css';
|
|
13
|
-
style.setAttribute('data-openagent-style', 'thought-chain');
|
|
14
|
-
style.setAttribute('data-openagent-host-version', CL.hostVersion || 'unknown');
|
|
15
|
-
style.textContent = `
|
|
16
|
-
/* ── Agent Pill(通用身份标签) ── */
|
|
17
|
-
.cl-agent-pill {
|
|
18
|
-
display: inline-flex;
|
|
19
|
-
align-items: center;
|
|
20
|
-
gap: 6px;
|
|
21
|
-
padding: 6px 10px;
|
|
22
|
-
border: 0.8px solid rgba(47,47,51,0.15);
|
|
23
|
-
border-radius: 6px;
|
|
24
|
-
background: #fff;
|
|
25
|
-
margin-bottom: 4px;
|
|
26
|
-
width: fit-content;
|
|
27
|
-
}
|
|
28
|
-
.cl-agent-pill-avatar {
|
|
29
|
-
width: 18px;
|
|
30
|
-
height: 18px;
|
|
31
|
-
border-radius: 50%;
|
|
32
|
-
object-fit: cover;
|
|
33
|
-
flex-shrink: 0;
|
|
34
|
-
}
|
|
35
|
-
.cl-agent-pill-name {
|
|
36
|
-
font-family: "PingFang SC", sans-serif;
|
|
37
|
-
font-size: 10px;
|
|
38
|
-
font-weight: 600;
|
|
39
|
-
color: #2F2F33;
|
|
40
|
-
white-space: nowrap;
|
|
41
|
-
line-height: 12px;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/* ── ThoughtChain 步骤容器 ── */
|
|
45
|
-
.cl-thought-chain {
|
|
46
|
-
margin: 0;
|
|
47
|
-
width: 100%;
|
|
48
|
-
box-sizing: border-box;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/* ── 分隔线 ── */
|
|
52
|
-
.cl-thought-chain-divider {
|
|
53
|
-
height: 0;
|
|
54
|
-
border: none;
|
|
55
|
-
border-top: 0.2px solid rgba(219, 219, 219, 1);
|
|
56
|
-
margin: 4px 0;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/* ── 标题栏 (状态文字) ── */
|
|
60
|
-
.cl-tools-collapse-header {
|
|
61
|
-
display: flex;
|
|
62
|
-
align-items: center;
|
|
63
|
-
gap: 4px;
|
|
64
|
-
cursor: pointer;
|
|
65
|
-
padding: 4px 0 2px 0;
|
|
66
|
-
user-select: none;
|
|
67
|
-
}
|
|
68
|
-
.cl-tools-collapse-header:hover { opacity: 0.8; }
|
|
69
|
-
|
|
70
|
-
.cl-tools-collapse-header-icon {
|
|
71
|
-
display: inline-block;
|
|
72
|
-
font-size: 8px;
|
|
73
|
-
color: #999;
|
|
74
|
-
transition: transform 0.25s ease;
|
|
75
|
-
line-height: 1;
|
|
76
|
-
}
|
|
77
|
-
.cl-tools-collapse-header-icon.cl-collapsed { transform: rotate(-90deg); }
|
|
78
|
-
|
|
79
|
-
.cl-tools-collapse-header-title {
|
|
80
|
-
font-family: "PingFang SC", sans-serif;
|
|
81
|
-
font-size: 10px;
|
|
82
|
-
font-weight: 600;
|
|
83
|
-
color: #2F2F33;
|
|
84
|
-
line-height: 12px;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/* ── 内容区 (折叠动画) ── */
|
|
88
|
-
.cl-tools-collapse-body {
|
|
89
|
-
overflow: hidden;
|
|
90
|
-
transition: max-height 0.35s ease, opacity 0.3s ease;
|
|
91
|
-
padding-left: 0;
|
|
92
|
-
}
|
|
93
|
-
.cl-tools-collapse-body.cl-expanded { max-height: 2000px; opacity: 1; }
|
|
94
|
-
.cl-tools-collapse-body.cl-collapsed { max-height: 0; opacity: 0; }
|
|
95
|
-
|
|
96
|
-
/* ── 步骤项 ── */
|
|
97
|
-
.cl-tools-collapse-step {
|
|
98
|
-
display: flex;
|
|
99
|
-
align-items: center;
|
|
100
|
-
gap: 8px;
|
|
101
|
-
padding: 3px 0;
|
|
102
|
-
position: relative;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.cl-tools-collapse-step-row {
|
|
106
|
-
display: flex;
|
|
107
|
-
align-items: center;
|
|
108
|
-
gap: 8px;
|
|
109
|
-
min-height: 16px;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/* ── 步骤圆点/图标 ── */
|
|
113
|
-
.cl-tools-collapse-step-icon {
|
|
114
|
-
width: 14px;
|
|
115
|
-
height: 14px;
|
|
116
|
-
flex-shrink: 0;
|
|
117
|
-
display: flex;
|
|
118
|
-
align-items: center;
|
|
119
|
-
justify-content: center;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/* 加载中:三点脉冲动画 (未完成/进行中) */
|
|
123
|
-
.cl-tools-collapse-step-dot {
|
|
124
|
-
display: flex;
|
|
125
|
-
align-items: center;
|
|
126
|
-
gap: 2px;
|
|
127
|
-
width: 14px;
|
|
128
|
-
height: 14px;
|
|
129
|
-
justify-content: center;
|
|
130
|
-
}
|
|
131
|
-
.cl-tools-collapse-step-dot::before,
|
|
132
|
-
.cl-tools-collapse-step-dot::after,
|
|
133
|
-
.cl-tools-collapse-step-dot span {
|
|
134
|
-
content: '';
|
|
135
|
-
display: block;
|
|
136
|
-
width: 3px;
|
|
137
|
-
height: 3px;
|
|
138
|
-
border-radius: 50%;
|
|
139
|
-
background: #bbb;
|
|
140
|
-
animation: cl-dot-pulse 1.2s ease-in-out infinite;
|
|
141
|
-
}
|
|
142
|
-
.cl-tools-collapse-step-dot::after { animation-delay: 0.2s; }
|
|
143
|
-
.cl-tools-collapse-step-dot span { animation-delay: 0.4s; }
|
|
144
|
-
@keyframes cl-dot-pulse {
|
|
145
|
-
0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); }
|
|
146
|
-
40% { opacity: 1; transform: scale(1.1); }
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/* 转圈 (当前步骤) */
|
|
150
|
-
.cl-tools-collapse-step-spinner {
|
|
151
|
-
width: 10px;
|
|
152
|
-
height: 10px;
|
|
153
|
-
border: 1.5px solid #999;
|
|
154
|
-
border-top-color: transparent;
|
|
155
|
-
border-radius: 50%;
|
|
156
|
-
animation: cl-spin 0.8s linear infinite;
|
|
157
|
-
}
|
|
158
|
-
@keyframes cl-spin { to { transform: rotate(360deg); } }
|
|
159
|
-
|
|
160
|
-
/* 完成 — 灰色实心圆点(Figma: Ellipse 12871, bg #dcdcdc) */
|
|
161
|
-
.cl-tools-collapse-step-check {
|
|
162
|
-
width: 10px;
|
|
163
|
-
height: 10px;
|
|
164
|
-
border-radius: 50%;
|
|
165
|
-
background: #dcdcdc;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/* ── 步骤标题文本 ── */
|
|
169
|
-
.cl-tools-collapse-step-title {
|
|
170
|
-
font-family: "PingFang SC", sans-serif;
|
|
171
|
-
font-size: 9.5px;
|
|
172
|
-
font-weight: 400;
|
|
173
|
-
color: #2F2F33;
|
|
174
|
-
line-height: 12.54px;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/* ── 步骤描述文本 ── */
|
|
178
|
-
.cl-tools-collapse-step-detail {
|
|
179
|
-
font-family: "PingFang SC", sans-serif;
|
|
180
|
-
font-size: 9px;
|
|
181
|
-
color: #999;
|
|
182
|
-
line-height: 12px;
|
|
183
|
-
margin-top: 1px;
|
|
184
|
-
padding-left: 22px;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
`;
|
|
188
|
-
document.head.appendChild(style);
|
|
189
|
-
})();
|
|
190
|
-
|
|
191
|
-
// ── 2. WebSocket 事件分发 ──
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
var _clWarnedMissingRenderHookHandler = false;
|
|
195
|
-
|
|
196
|
-
CL.handleDelegateWsEvent = function (msg) {
|
|
197
|
-
if (window.__cl_handleStreamEvent) {
|
|
198
|
-
window.__cl_handleStreamEvent(msg);
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// RenderHook is the only remote-agent ToolCard path. Do not fall back to
|
|
203
|
-
// mutating native .chat-tool-card DOM here; missing handler should be visible
|
|
204
|
-
// during debugging instead of being masked by the legacy path.
|
|
205
|
-
if (!_clWarnedMissingRenderHookHandler && msg && msg.stream === 'tool') {
|
|
206
|
-
console.warn('[cl-ws-gate] RenderHook stream handler missing; remote-agent tool event ignored');
|
|
207
|
-
_clWarnedMissingRenderHookHandler = true;
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
// JSON.parse 拦截已移至 IIFE 顶部(在 bundle 加载前执行)
|