openclaw-openagent 1.0.9 → 1.0.12

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.
Files changed (64) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/src/app/remote-agent-tool.js +110 -14
  3. package/dist/src/app/types.d.ts +2 -2
  4. package/dist/src/plugin-ui/adapters/adapters/oc-2026-04.js +103 -0
  5. package/dist/src/plugin-ui/adapters/adapters/oc-2026-05.js +125 -0
  6. package/dist/src/plugin-ui/adapters/adapters/oc-2026-06.js +125 -0
  7. package/dist/src/plugin-ui/adapters/adapters/oc-unknown.js +48 -0
  8. package/dist/src/plugin-ui/adapters/oc-2026-04.js +103 -0
  9. package/dist/src/plugin-ui/adapters/oc-2026-05.js +125 -0
  10. package/dist/src/plugin-ui/adapters/oc-2026-06.js +125 -0
  11. package/dist/src/plugin-ui/adapters/oc-unknown.js +48 -0
  12. package/dist/src/plugin-ui/assets/bg.png +0 -0
  13. package/dist/src/plugin-ui/assets/icon.png +0 -0
  14. package/dist/src/plugin-ui/assets/openagent-override.js +2480 -1004
  15. package/dist/src/plugin-ui/index.d.ts +1 -1
  16. package/dist/src/plugin-ui/index.js +2 -2
  17. package/dist/src/plugin-ui/ui-extension-loader/index.d.ts +2 -1
  18. package/dist/src/plugin-ui/ui-extension-loader/index.js +5 -5
  19. package/dist/src/plugin-ui/ui-extension-loader/registry-regex.js +128 -13
  20. package/dist/src/plugin-ui/ui-extension-loader/types.d.ts +4 -1
  21. package/dist/src/state/store.d.ts +21 -0
  22. package/dist/src/state/store.js +54 -0
  23. package/dist/src/transport/oasn/oasn-invocation.d.ts +3 -0
  24. package/dist/src/transport/oasn/oasn-invocation.js +28 -12
  25. package/dist/src/transport/oasn/oasn-types.d.ts +8 -4
  26. package/index.ts +1 -1
  27. package/openclaw.plugin.json +1 -1
  28. package/package.json +5 -4
  29. package/src/app/remote-agent-tool.ts +131 -16
  30. package/src/app/types.ts +2 -2
  31. package/src/plugin-ui/adapters/oc-2026-04.js +103 -0
  32. package/src/plugin-ui/adapters/oc-2026-05.js +125 -0
  33. package/src/plugin-ui/adapters/oc-2026-06.js +125 -0
  34. package/src/plugin-ui/adapters/oc-unknown.js +48 -0
  35. package/src/plugin-ui/assets/bg.png +0 -0
  36. package/src/plugin-ui/assets/icon.png +0 -0
  37. package/src/plugin-ui/assets/openagent-override.js +2480 -1004
  38. package/src/plugin-ui/build.cjs +309 -23
  39. package/src/plugin-ui/index.ts +2 -2
  40. package/src/plugin-ui/modules/agent-book/panel/agent-book.js +187 -14
  41. package/src/plugin-ui/modules/agent-book/panel/agent-card.js +26 -10
  42. package/src/plugin-ui/modules/agent-book/panel/agent-data.js +1 -1
  43. package/src/plugin-ui/modules/agent-book/panel/inject-ui.js +149 -1
  44. package/src/plugin-ui/modules/agent-book/panel/styles.js +352 -210
  45. package/src/plugin-ui/modules/agent-book/remote-agent-tool/components-core.js +4 -2
  46. package/src/plugin-ui/modules/agent-book/remote-agent-tool/thought-chain-card.js +4 -1
  47. package/src/plugin-ui/modules/agent-book/scanner.js +17 -5
  48. package/src/plugin-ui/modules/agent-book/travelcard/travel-styles.js +5 -0
  49. package/src/plugin-ui/modules/loader/bootstrap.js +1 -1
  50. package/src/plugin-ui/modules/loader/shared-state.js +278 -0
  51. package/src/plugin-ui/modules/remote-agent/execution-card.js +385 -124
  52. package/src/plugin-ui/modules/remote-agent/native-style-adapter.js +5 -23
  53. package/src/plugin-ui/modules/remote-agent/output-card.js +97 -31
  54. package/src/plugin-ui/modules/remote-agent/render-hooks.js +149 -58
  55. package/src/plugin-ui/modules/remote-agent/styles.js +690 -523
  56. package/src/plugin-ui/modules/remote-agent/tool-card-model.js +77 -3
  57. package/src/plugin-ui/postinstall-deploy.cjs +52 -0
  58. package/src/plugin-ui/ui-extension-loader/index.ts +6 -6
  59. package/src/plugin-ui/ui-extension-loader/registry-regex.ts +131 -14
  60. package/src/plugin-ui/ui-extension-loader/types.ts +5 -1
  61. package/src/state/store.ts +80 -0
  62. package/src/transport/oasn/oasn-invocation.ts +47 -12
  63. package/src/transport/oasn/oasn-types.ts +6 -2
  64. package/src/types/openclaw-plugin-sdk-media-store.d.ts +9 -0
package/dist/index.js CHANGED
@@ -101,7 +101,7 @@ export default {
101
101
  logger.warn(`[entry] registerHttpRoute failed: ${routeErr.message}`);
102
102
  }
103
103
  // Auto-inject Control UI override (copies openagent-override.js + patches)
104
- injectControlUiOverride().catch(err => {
104
+ injectControlUiOverride(api.runtime?.version).catch(err => {
105
105
  logger.warn(`[entry] Control UI injection failed: ${err.message}`);
106
106
  });
107
107
  logger.info('[entry] Tools + hooks registered (full mode)');
@@ -173,13 +173,19 @@ function formatMediaDownloadLines(urls) {
173
173
  .map((url) => `- [${mediaDownloadLabel(url)}](${url})`);
174
174
  return lines.length ? `下载链接:\n${lines.join('\n')}` : '';
175
175
  }
176
- function normalizeRemoteToolExecuteArgs(signalOrUpdate, onUpdateOrContext, legacySignal) {
176
+ function normalizeRemoteToolExecuteArgs(signalOrUpdate, onUpdateOrContext, contextOrSignal) {
177
+ const contextCandidate = (value) => {
178
+ if (!value || typeof value !== 'object' || isAbortSignalLike(value))
179
+ return undefined;
180
+ return value;
181
+ };
177
182
  if (typeof signalOrUpdate === 'function') {
178
183
  return {
179
184
  onUpdate: signalOrUpdate,
180
- signal: isAbortSignalLike(legacySignal)
181
- ? legacySignal
185
+ signal: isAbortSignalLike(contextOrSignal)
186
+ ? contextOrSignal
182
187
  : getObjectSignal(onUpdateOrContext),
188
+ context: contextCandidate(onUpdateOrContext),
183
189
  signature: 'legacy:update-third',
184
190
  };
185
191
  }
@@ -187,7 +193,8 @@ function normalizeRemoteToolExecuteArgs(signalOrUpdate, onUpdateOrContext, legac
187
193
  return {
188
194
  signal: isAbortSignalLike(signalOrUpdate) ? signalOrUpdate : undefined,
189
195
  onUpdate: onUpdateOrContext,
190
- signature: 'modern:signal-update',
196
+ context: contextCandidate(contextOrSignal),
197
+ signature: contextCandidate(contextOrSignal) ? 'modern:signal-update-context' : 'modern:signal-update',
191
198
  };
192
199
  }
193
200
  const nestedUpdate = getObjectCallback(onUpdateOrContext, 'onUpdate') ||
@@ -195,13 +202,87 @@ function normalizeRemoteToolExecuteArgs(signalOrUpdate, onUpdateOrContext, legac
195
202
  getObjectCallback(onUpdateOrContext, 'onToolUpdate');
196
203
  const nestedSignal = isAbortSignalLike(signalOrUpdate)
197
204
  ? signalOrUpdate
198
- : getObjectSignal(onUpdateOrContext) || (isAbortSignalLike(legacySignal) ? legacySignal : undefined);
205
+ : getObjectSignal(onUpdateOrContext) || (isAbortSignalLike(contextOrSignal) ? contextOrSignal : undefined);
199
206
  return {
200
207
  signal: nestedSignal,
201
208
  onUpdate: nestedUpdate,
209
+ context: contextCandidate(contextOrSignal) || contextCandidate(onUpdateOrContext),
202
210
  signature: nestedUpdate ? 'context:update-callback' : 'unknown:no-update',
203
211
  };
204
212
  }
213
+ function readNonEmptyString(value) {
214
+ return typeof value === 'string' && value.trim() ? value.trim() : undefined;
215
+ }
216
+ function readRecord(value) {
217
+ return value && typeof value === 'object' ? value : undefined;
218
+ }
219
+ function callStringGetter(target, methodName) {
220
+ const record = readRecord(target);
221
+ const fn = record?.[methodName];
222
+ if (typeof fn !== 'function')
223
+ return undefined;
224
+ try {
225
+ return readNonEmptyString(fn.call(target));
226
+ }
227
+ catch {
228
+ return undefined;
229
+ }
230
+ }
231
+ function readNestedString(root, path) {
232
+ let cur = root;
233
+ for (const key of path) {
234
+ const record = readRecord(cur);
235
+ if (!record)
236
+ return undefined;
237
+ cur = record[key];
238
+ }
239
+ return readNonEmptyString(cur);
240
+ }
241
+ function resolveOpenclawSessionKey(context) {
242
+ const ctx = readRecord(context);
243
+ if (!ctx)
244
+ return undefined;
245
+ const sessionManager = ctx.sessionManager;
246
+ const managerSessionId = callStringGetter(sessionManager, 'getSessionId');
247
+ if (managerSessionId)
248
+ return `session:${managerSessionId}`;
249
+ const directSessionId = readNonEmptyString(ctx.sessionId) ||
250
+ readNonEmptyString(ctx.openclawSessionId) ||
251
+ readNonEmptyString(ctx.agentSessionId) ||
252
+ readNestedString(ctx, ['session', 'sessionId']);
253
+ if (directSessionId)
254
+ return `session:${directSessionId}`;
255
+ const sessionFile = callStringGetter(sessionManager, 'getSessionFile') ||
256
+ readNestedString(ctx, ['session', 'sessionFile']);
257
+ if (sessionFile)
258
+ return `file:${sessionFile}`;
259
+ return undefined;
260
+ }
261
+ function getRememberedRemoteSessionId(runtime, openclawSessionKey, agentId) {
262
+ if (!openclawSessionKey)
263
+ return undefined;
264
+ try {
265
+ return runtime.store?.getRemoteAgentSession?.(openclawSessionKey, agentId) || undefined;
266
+ }
267
+ catch (err) {
268
+ logger.warn(`[remote-tool] Failed to read remembered OASN session: ${err.message}`);
269
+ return undefined;
270
+ }
271
+ }
272
+ function rememberRemoteSessionId(runtime, openclawSessionKey, agentId, sessionId) {
273
+ if (!openclawSessionKey || !sessionId)
274
+ return;
275
+ try {
276
+ runtime.store?.upsertRemoteAgentSession?.({
277
+ openclaw_session_key: openclawSessionKey,
278
+ target_agent_id: agentId,
279
+ session_id: sessionId,
280
+ });
281
+ }
282
+ catch (err) {
283
+ logger.warn(`[remote-tool] Failed to remember OASN session: ${err.message}`);
284
+ }
285
+ }
205
286
  // ── Tool Factory ──
206
287
  /**
207
288
  * Create the openagent_call_remote_agent tool.
@@ -217,9 +298,9 @@ export function createCallRemoteAgentTool() {
217
298
  name: 'openagent_call_remote_agent',
218
299
  label: 'Call Remote Agent',
219
300
  description: 'Route a user request to a remote specialist Agent via the OpenAgent network. ' +
220
- 'TRIGGER: When the user message contains a {openagent_call_remote_agent:agent_id="...",agent_name="...",instruction="..."} marker, ' +
301
+ 'TRIGGER: When the user message contains a {openagent_call_remote_agent:agent_id="...",agent_name="...",agent_bio="...",instruction="..."} marker, ' +
221
302
  'call this tool to forward the request to the specified remote Agent. ' +
222
- 'Extract agent_id and agent_name from the marker; use the remaining natural-language text as the task parameter. ' +
303
+ 'Extract agent_id, agent_name, and optional agent_bio from the marker; use the remaining natural-language text as the task parameter. ' +
223
304
  'Do not display the raw marker to the user. ' +
224
305
  'mode "session" (default) preserves remote conversation history; mode "run" starts fresh — include full context in task.',
225
306
  parameters: {
@@ -233,6 +314,10 @@ export function createCallRemoteAgentTool() {
233
314
  type: 'string',
234
315
  description: 'Display name of the remote Agent from the marker. Use this in your reply to the user.',
235
316
  },
317
+ agent_bio: {
318
+ type: 'string',
319
+ description: 'Short description of the remote Agent from the marker. Preserve it for UI display.',
320
+ },
236
321
  task: {
237
322
  type: 'string',
238
323
  description: 'The user\'s natural-language request text, excluding the marker.',
@@ -253,12 +338,12 @@ export function createCallRemoteAgentTool() {
253
338
  },
254
339
  required: ['agent_id', 'agent_name', 'task'],
255
340
  },
256
- async execute(_id, params, signalOrUpdate, onUpdateOrContext, legacySignal) {
257
- const { signal, onUpdate, signature } = normalizeRemoteToolExecuteArgs(signalOrUpdate, onUpdateOrContext, legacySignal);
341
+ async execute(_id, params, signalOrUpdate, onUpdateOrContext, contextOrSignal) {
342
+ const { signal, onUpdate, context, signature } = normalizeRemoteToolExecuteArgs(signalOrUpdate, onUpdateOrContext, contextOrSignal);
258
343
  logger.info(`[remote-tool] Execute args: toolCallId=${String(_id)} signature=${signature} ` +
259
344
  `hasSignal=${Boolean(signal)} hasOnUpdate=${Boolean(onUpdate)} ` +
260
345
  `third=${describeExecuteArg(signalOrUpdate)} fourth=${describeExecuteArg(onUpdateOrContext)} ` +
261
- `fifth=${describeExecuteArg(legacySignal)}`);
346
+ `fifth=${describeExecuteArg(contextOrSignal)}`);
262
347
  // ① Check runtime (same pattern as messaging-tools.ts)
263
348
  const rt = registry.getDefault();
264
349
  if (!rt || !rt.isRunning) {
@@ -275,7 +360,7 @@ export function createCallRemoteAgentTool() {
275
360
  }
276
361
  const agentId = String(params.agent_id || '').trim();
277
362
  const task = String(params.task || '').trim();
278
- const mode = String(params.mode || 'session').trim();
363
+ const mode = String(params.mode || 'session').trim() === 'run' ? 'run' : 'session';
279
364
  // ② Validate required params
280
365
  if (!agentId) {
281
366
  logger.warn('[remote-tool] Missing agent_id parameter');
@@ -334,14 +419,19 @@ export function createCallRemoteAgentTool() {
334
419
  const inputFileRefs = Array.isArray(params.input_file_refs)
335
420
  ? params.input_file_refs.filter((r) => typeof r === 'string' && r.trim())
336
421
  : undefined;
422
+ const openclawSessionKey = resolveOpenclawSessionKey(context);
423
+ const rememberedSessionId = mode === 'session'
424
+ ? getRememberedRemoteSessionId(rt, openclawSessionKey, agentId)
425
+ : undefined;
426
+ if (mode === 'session' && !openclawSessionKey) {
427
+ logger.warn('[remote-tool] OASN session mode requested but OpenClaw session scope is unavailable');
428
+ }
337
429
  const taskReq = {
338
430
  requestId,
339
431
  task,
432
+ sessionId: rememberedSessionId,
340
433
  inputFileRefs: inputFileRefs?.length ? inputFileRefs : undefined,
341
434
  timeoutMs: OASN_INVOCATION_TIMEOUT_MS,
342
- // mode='session' 时不在协议层 join 已有 session(OASN 默认每次起新 Invocation)。
343
- // 上游若需要保留对话历史,请在 task 文本里显式带 session_id;
344
- // 暂不在工具层做 session 续传,避免误用导致跨用户串号。
345
435
  };
346
436
  let handle;
347
437
  try {
@@ -353,6 +443,9 @@ export function createCallRemoteAgentTool() {
353
443
  }
354
444
  logger.info(`[remote-tool] OASN invocation created: invocationId=${handle.invocationId} ` +
355
445
  `sessionId=${handle.sessionId ?? '-'} effectiveTimeoutMs=${handle.effectiveTimeoutMs ?? '-'}`);
446
+ if (mode === 'session') {
447
+ rememberRemoteSessionId(rt, openclawSessionKey, agentId, handle.sessionId);
448
+ }
356
449
  try {
357
450
  const result = await oasnTransport.waitForTaskResult(handle, {
358
451
  timeoutMs: TIMEOUT_MS,
@@ -362,6 +455,9 @@ export function createCallRemoteAgentTool() {
362
455
  const artifacts = result.artifacts ?? [];
363
456
  let content = result.content;
364
457
  let mediaUrls = [];
458
+ if (mode === 'session') {
459
+ rememberRemoteSessionId(rt, openclawSessionKey, agentId, result.webuiContinuation?.sessionId);
460
+ }
365
461
  if (!content.trim()) {
366
462
  for (const textArtifact of artifacts) {
367
463
  if (!textArtifact.contentUrl && !textArtifact.contentAvailable)
@@ -44,7 +44,7 @@ export interface ToolDescriptor {
44
44
  * Execute the tool.
45
45
  *
46
46
  * OpenClaw runtime usually calls:
47
- * tool.execute(toolCallId, params, signal, onUpdate)
47
+ * tool.execute(toolCallId, params, signal, onUpdate, ctx)
48
48
  *
49
49
  * Older adapters used:
50
50
  * tool.execute(toolCallId, params, onUpdate, ctx, signal)
@@ -54,7 +54,7 @@ export interface ToolDescriptor {
54
54
  *
55
55
  * @see docs/reference/openclaw/v2026.3.23/dist/pi-embedded-CswW9luA.js L169823
56
56
  */
57
- execute: (_id: unknown, params: ToolParams, signalOrUpdate?: AbortSignal | ToolUpdateCallback, onUpdateOrContext?: ToolUpdateCallback | unknown, legacySignal?: AbortSignal) => Promise<ToolResult>;
57
+ execute: (_id: unknown, params: ToolParams, signalOrUpdate?: AbortSignal | ToolUpdateCallback, onUpdateOrContext?: ToolUpdateCallback | unknown, contextOrSignal?: unknown) => Promise<ToolResult>;
58
58
  }
59
59
  export type ToolFactory = () => ToolDescriptor;
60
60
  /** Helper: create a successful text result in SDK format */
@@ -0,0 +1,103 @@
1
+ // ── OpenClaw 2026.4 host adapter ──
2
+ // Host DOM: chat-tool-msg-collapse -> chat-tool-msg-body -> chat-tool-card.
3
+
4
+ (function _clInstallHostAdapter202604() {
5
+ function _matches(node, selector) {
6
+ return !!(node && selector && node.matches && node.matches(selector));
7
+ }
8
+
9
+ var adapter = {
10
+ id: 'oc-2026-04',
11
+ family: '2026.4',
12
+ css: {
13
+ remoteShell: [
14
+ 'details.chat-tool-msg-collapse:has(.cl-remote-agent-card)',
15
+ '.chat-tool-msg-collapse:has(.cl-remote-agent-card)',
16
+ ],
17
+ outputHostMargin: [],
18
+ outputHostMarginReset: [
19
+ 'details.chat-tool-msg-collapse:has(.cl-remote-agent-card)',
20
+ '.chat-tool-msg-collapse:has(.cl-remote-agent-card)',
21
+ ],
22
+ summaryHidden: [
23
+ 'details.chat-tool-msg-collapse:has(.cl-remote-agent-card) > summary.chat-tool-msg-summary',
24
+ '.chat-tool-msg-collapse:has(.cl-remote-agent-card) > .chat-tool-msg-summary',
25
+ ],
26
+ hostShellRawText: [
27
+ '.chat-tool-msg-body.cl-remote-agent-host-shell > .chat-text',
28
+ ],
29
+ rawTextCardHosts: [
30
+ '.chat-tool-msg-body:has(.cl-remote-agent-card) > .chat-text',
31
+ '.chat-tool-card__detail:has(.cl-remote-agent-card) > .chat-text',
32
+ ],
33
+ rawTextPlaceholderHosts: [
34
+ '.chat-tool-msg-body:has(.cl-remote-agent-output-placeholder) > .chat-text',
35
+ '.chat-tool-card__detail:has(.cl-remote-agent-output-placeholder) > .chat-text',
36
+ ],
37
+ hostBody: [
38
+ 'details.chat-tool-msg-collapse:has(.cl-remote-agent-card) > .chat-tool-msg-body',
39
+ '.chat-tool-msg-collapse:has(.cl-remote-agent-card) > .chat-tool-msg-body',
40
+ ],
41
+ manualOpenReset: [
42
+ '.chat-tool-msg-collapse.chat-tool-msg-collapse--manual.is-open:has(.cl-remote-agent-card)',
43
+ ],
44
+ hostShellReset: [
45
+ '.cl-remote-agent-host-shell.chat-tool-card',
46
+ '.cl-remote-agent-host-shell.chat-tool-card__detail',
47
+ '.cl-remote-agent-host-shell.chat-tool-msg-body',
48
+ 'details.cl-remote-agent-host-shell',
49
+ ],
50
+ hostShellSummary: [
51
+ '.cl-remote-agent-host-shell > summary.chat-tool-msg-summary',
52
+ '.cl-remote-agent-host-shell > .chat-tool-msg-summary',
53
+ ],
54
+ modernCardLayout: false,
55
+ },
56
+ nativeStyle: {
57
+ shellSelectors: [
58
+ '.chat-tool-card:not(:has(.cl-remote-agent-card))',
59
+ '.chat-tool-msg-collapse:not(:has(.cl-remote-agent-card))',
60
+ ],
61
+ summarySelectors: [
62
+ '.chat-tool-card__header',
63
+ '.chat-tool-card__title',
64
+ '.chat-tool-msg-summary:not(.cl-remote-agent-host-shell *)',
65
+ ],
66
+ indentSelectors: [
67
+ '.chat-group.tool:not(:has(.cl-remote-agent-card))',
68
+ '.chat-bubble:not(:has(.cl-remote-agent-card))',
69
+ ],
70
+ },
71
+ selectors: {
72
+ textContext: '.chat-text, .chat-tool-card__detail, .chat-tool-msg-body',
73
+ summary: ':scope > .chat-tool-msg-summary, .chat-tool-msg-summary',
74
+ forceOpenHeader: '.chat-tool-msg-summary',
75
+ rawTextHostClosest: [
76
+ '.chat-tool-msg-body',
77
+ '.chat-tool-card__detail',
78
+ '.chat-bubble',
79
+ ],
80
+ rawTextHostsWithinShell: '.chat-tool-msg-body, .chat-tool-card__detail, .chat-bubble',
81
+ },
82
+ isRemoteNativeToolShellCandidate: function(node) {
83
+ return _matches(node, 'details.chat-tool-msg-collapse, .chat-tool-msg-collapse, .chat-tool-card');
84
+ },
85
+ isNativeToolShell: function(node) {
86
+ return _matches(node, 'details.chat-tool-msg-collapse, .chat-tool-msg-collapse');
87
+ },
88
+ isToolLikeShell: function(node) {
89
+ return _matches(node, 'details.chat-tool-msg-collapse, .chat-tool-msg-collapse, .chat-tool-card, .chat-tool-msg-body, .chat-tool-card__detail');
90
+ },
91
+ isToolBody: function(node) {
92
+ return _matches(node, '.chat-tool-msg-body');
93
+ },
94
+ isMarkableHost: function(node) {
95
+ return _matches(node, 'details.chat-tool-msg-collapse, .chat-tool-card, .chat-tool-card__detail, .chat-tool-msg-body');
96
+ },
97
+ };
98
+
99
+ CL.hostAdapter = adapter;
100
+ try {
101
+ document.documentElement.setAttribute('data-openagent-host-adapter', adapter.id);
102
+ } catch (e) {}
103
+ })();
@@ -0,0 +1,125 @@
1
+ // ── OpenClaw 2026.5 host adapter ──
2
+ // Host DOM uses the newer tools-collapse family, with msg-collapse kept as a
3
+ // compatible secondary path for mixed 2026.5 builds.
4
+
5
+ (function _clInstallHostAdapter202605() {
6
+ function _matches(node, selector) {
7
+ return !!(node && selector && node.matches && node.matches(selector));
8
+ }
9
+
10
+ var adapter = {
11
+ id: 'oc-2026-05',
12
+ family: '2026.5',
13
+ css: {
14
+ remoteShell: [
15
+ 'details.chat-tools-collapse:has(.cl-remote-agent-card)',
16
+ 'details.chat-tool-msg-collapse:has(.cl-remote-agent-card)',
17
+ '.chat-tools-collapse:has(.cl-remote-agent-card)',
18
+ '.chat-tool-msg-collapse:has(.cl-remote-agent-card)',
19
+ ],
20
+ outputHostMargin: [
21
+ 'details.chat-tools-collapse:has(.cl-output-card)',
22
+ '.chat-tools-collapse:has(.cl-output-card)',
23
+ 'details.chat-tool-msg-collapse:has(.cl-remote-agent-card)',
24
+ '.chat-tool-msg-collapse:has(.cl-remote-agent-card)',
25
+ ],
26
+ outputHostMarginReset: [],
27
+ summaryHidden: [
28
+ 'details.chat-tools-collapse:has(.cl-remote-agent-card) > summary.chat-tools-summary',
29
+ 'details.chat-tool-msg-collapse:has(.cl-remote-agent-card) > summary.chat-tool-msg-summary',
30
+ '.chat-tools-collapse:has(.cl-remote-agent-card) > .chat-tools-summary',
31
+ '.chat-tool-msg-collapse:has(.cl-remote-agent-card) > .chat-tool-msg-summary',
32
+ ],
33
+ hostShellRawText: [
34
+ '.chat-tools-collapse__body.cl-remote-agent-host-shell > .chat-text',
35
+ '.chat-tool-msg-body.cl-remote-agent-host-shell > .chat-text',
36
+ ],
37
+ rawTextCardHosts: [
38
+ '.chat-tools-collapse__body:has(.cl-remote-agent-card) > .chat-text',
39
+ '.chat-tool-msg-body:has(.cl-remote-agent-card) > .chat-text',
40
+ '.chat-tool-card__detail:has(.cl-remote-agent-card) > .chat-text',
41
+ ],
42
+ rawTextPlaceholderHosts: [
43
+ '.chat-tools-collapse__body:has(.cl-remote-agent-output-placeholder) > .chat-text',
44
+ '.chat-tool-msg-body:has(.cl-remote-agent-output-placeholder) > .chat-text',
45
+ '.chat-tool-card__detail:has(.cl-remote-agent-output-placeholder) > .chat-text',
46
+ ],
47
+ hostBody: [
48
+ 'details.chat-tools-collapse:has(.cl-remote-agent-card) > .chat-tools-collapse__body',
49
+ 'details.chat-tool-msg-collapse:has(.cl-remote-agent-card) > .chat-tool-msg-body',
50
+ '.chat-tools-collapse:has(.cl-remote-agent-card) > .chat-tools-collapse__body',
51
+ '.chat-tool-msg-collapse:has(.cl-remote-agent-card) > .chat-tool-msg-body',
52
+ ],
53
+ manualOpenReset: [
54
+ '.chat-tool-msg-collapse.chat-tool-msg-collapse--manual.is-open:has(.cl-remote-agent-card)',
55
+ ],
56
+ hostShellReset: [
57
+ '.cl-remote-agent-host-shell.chat-tool-card',
58
+ '.cl-remote-agent-host-shell.chat-tool-card__detail',
59
+ '.cl-remote-agent-host-shell.chat-tools-collapse__body',
60
+ '.cl-remote-agent-host-shell.chat-tool-msg-body',
61
+ 'details.cl-remote-agent-host-shell',
62
+ ],
63
+ hostShellSummary: [
64
+ '.cl-remote-agent-host-shell > summary.chat-tools-summary',
65
+ '.cl-remote-agent-host-shell > summary.chat-tool-msg-summary',
66
+ '.cl-remote-agent-host-shell > .chat-tools-summary',
67
+ '.cl-remote-agent-host-shell > .chat-tool-msg-summary',
68
+ ],
69
+ modernCardLayout: true,
70
+ },
71
+ nativeStyle: {
72
+ shellSelectors: [
73
+ '.chat-tool-card:not(:has(.cl-remote-agent-card))',
74
+ '.chat-tool-msg-collapse:not(:has(.cl-remote-agent-card))',
75
+ '.chat-tools-collapse:not(:has(.cl-remote-agent-card))',
76
+ '.tool-card:not(:has(.cl-remote-agent-card))',
77
+ '.chat-tool-card__wrapper:not(:has(.cl-remote-agent-card))',
78
+ ],
79
+ summarySelectors: [
80
+ '.chat-tool-card__header',
81
+ '.chat-tool-card__title',
82
+ '.chat-tool-msg-summary:not(.cl-remote-agent-host-shell *)',
83
+ '.chat-tools-summary:not(.cl-remote-agent-host-shell *)',
84
+ '.tool-card__header',
85
+ '.tool-card__title',
86
+ ],
87
+ indentSelectors: [
88
+ '.chat-group.tool:not(:has(.cl-remote-agent-card))',
89
+ '.chat-bubble:not(:has(.cl-remote-agent-card))',
90
+ ],
91
+ },
92
+ selectors: {
93
+ textContext: '.chat-text, .chat-tool-card__detail, .chat-tool-msg-body, .chat-tools-collapse__body',
94
+ summary: ':scope > summary, :scope > .chat-tools-summary, :scope > .chat-tool-msg-summary, .chat-tools-summary, .chat-tool-msg-summary',
95
+ forceOpenHeader: '.chat-tool-msg-summary, .chat-tools-summary',
96
+ rawTextHostClosest: [
97
+ '.chat-tools-collapse__body',
98
+ '.chat-tool-msg-body',
99
+ '.chat-tool-card__detail',
100
+ '.chat-bubble',
101
+ ],
102
+ rawTextHostsWithinShell: '.chat-tools-collapse__body, .chat-tool-msg-body, .chat-tool-card__detail, .chat-bubble',
103
+ },
104
+ isRemoteNativeToolShellCandidate: function(node) {
105
+ return _matches(node, 'details.chat-tools-collapse, details.chat-tool-msg-collapse, .chat-tools-collapse, .chat-tool-msg-collapse, .chat-tool-card');
106
+ },
107
+ isNativeToolShell: function(node) {
108
+ return _matches(node, 'details.chat-tools-collapse, details.chat-tool-msg-collapse, .chat-tools-collapse, .chat-tool-msg-collapse');
109
+ },
110
+ isToolLikeShell: function(node) {
111
+ return _matches(node, 'details.chat-tools-collapse, details.chat-tool-msg-collapse, .chat-tools-collapse, .chat-tool-msg-collapse, .chat-tool-card, .chat-tools-collapse__body, .chat-tool-msg-body, .chat-tool-card__detail');
112
+ },
113
+ isToolBody: function(node) {
114
+ return _matches(node, '.chat-tools-collapse__body, .chat-tool-msg-body');
115
+ },
116
+ isMarkableHost: function(node) {
117
+ return _matches(node, 'details.chat-tools-collapse, details.chat-tool-msg-collapse, .chat-tool-card, .chat-tool-card__detail, .chat-tools-collapse__body, .chat-tool-msg-body');
118
+ },
119
+ };
120
+
121
+ CL.hostAdapter = adapter;
122
+ try {
123
+ document.documentElement.setAttribute('data-openagent-host-adapter', adapter.id);
124
+ } catch (e) {}
125
+ })();
@@ -0,0 +1,125 @@
1
+ // ── OpenClaw 2026.6 host adapter ──
2
+ // 2026.6 uses the V2 OpenAgent card path and the newer tools-collapse host
3
+ // structure. Selector values intentionally mirror the 2026.5 adapter.
4
+
5
+ (function _clInstallHostAdapter202606() {
6
+ function _matches(node, selector) {
7
+ return !!(node && selector && node.matches && node.matches(selector));
8
+ }
9
+
10
+ var adapter = {
11
+ id: 'oc-2026-06',
12
+ family: '2026.6',
13
+ css: {
14
+ remoteShell: [
15
+ 'details.chat-tools-collapse:has(.cl-remote-agent-card)',
16
+ 'details.chat-tool-msg-collapse:has(.cl-remote-agent-card)',
17
+ '.chat-tools-collapse:has(.cl-remote-agent-card)',
18
+ '.chat-tool-msg-collapse:has(.cl-remote-agent-card)',
19
+ ],
20
+ outputHostMargin: [
21
+ 'details.chat-tools-collapse:has(.cl-output-card)',
22
+ '.chat-tools-collapse:has(.cl-output-card)',
23
+ 'details.chat-tool-msg-collapse:has(.cl-remote-agent-card)',
24
+ '.chat-tool-msg-collapse:has(.cl-remote-agent-card)',
25
+ ],
26
+ outputHostMarginReset: [],
27
+ summaryHidden: [
28
+ 'details.chat-tools-collapse:has(.cl-remote-agent-card) > summary.chat-tools-summary',
29
+ 'details.chat-tool-msg-collapse:has(.cl-remote-agent-card) > summary.chat-tool-msg-summary',
30
+ '.chat-tools-collapse:has(.cl-remote-agent-card) > .chat-tools-summary',
31
+ '.chat-tool-msg-collapse:has(.cl-remote-agent-card) > .chat-tool-msg-summary',
32
+ ],
33
+ hostShellRawText: [
34
+ '.chat-tools-collapse__body.cl-remote-agent-host-shell > .chat-text',
35
+ '.chat-tool-msg-body.cl-remote-agent-host-shell > .chat-text',
36
+ ],
37
+ rawTextCardHosts: [
38
+ '.chat-tools-collapse__body:has(.cl-remote-agent-card) > .chat-text',
39
+ '.chat-tool-msg-body:has(.cl-remote-agent-card) > .chat-text',
40
+ '.chat-tool-card__detail:has(.cl-remote-agent-card) > .chat-text',
41
+ ],
42
+ rawTextPlaceholderHosts: [
43
+ '.chat-tools-collapse__body:has(.cl-remote-agent-output-placeholder) > .chat-text',
44
+ '.chat-tool-msg-body:has(.cl-remote-agent-output-placeholder) > .chat-text',
45
+ '.chat-tool-card__detail:has(.cl-remote-agent-output-placeholder) > .chat-text',
46
+ ],
47
+ hostBody: [
48
+ 'details.chat-tools-collapse:has(.cl-remote-agent-card) > .chat-tools-collapse__body',
49
+ 'details.chat-tool-msg-collapse:has(.cl-remote-agent-card) > .chat-tool-msg-body',
50
+ '.chat-tools-collapse:has(.cl-remote-agent-card) > .chat-tools-collapse__body',
51
+ '.chat-tool-msg-collapse:has(.cl-remote-agent-card) > .chat-tool-msg-body',
52
+ ],
53
+ manualOpenReset: [
54
+ '.chat-tool-msg-collapse.chat-tool-msg-collapse--manual.is-open:has(.cl-remote-agent-card)',
55
+ ],
56
+ hostShellReset: [
57
+ '.cl-remote-agent-host-shell.chat-tool-card',
58
+ '.cl-remote-agent-host-shell.chat-tool-card__detail',
59
+ '.cl-remote-agent-host-shell.chat-tools-collapse__body',
60
+ '.cl-remote-agent-host-shell.chat-tool-msg-body',
61
+ 'details.cl-remote-agent-host-shell',
62
+ ],
63
+ hostShellSummary: [
64
+ '.cl-remote-agent-host-shell > summary.chat-tools-summary',
65
+ '.cl-remote-agent-host-shell > summary.chat-tool-msg-summary',
66
+ '.cl-remote-agent-host-shell > .chat-tools-summary',
67
+ '.cl-remote-agent-host-shell > .chat-tool-msg-summary',
68
+ ],
69
+ modernCardLayout: true,
70
+ },
71
+ nativeStyle: {
72
+ shellSelectors: [
73
+ '.chat-tool-card:not(:has(.cl-remote-agent-card))',
74
+ '.chat-tool-msg-collapse:not(:has(.cl-remote-agent-card))',
75
+ '.chat-tools-collapse:not(:has(.cl-remote-agent-card))',
76
+ '.tool-card:not(:has(.cl-remote-agent-card))',
77
+ '.chat-tool-card__wrapper:not(:has(.cl-remote-agent-card))',
78
+ ],
79
+ summarySelectors: [
80
+ '.chat-tool-card__header',
81
+ '.chat-tool-card__title',
82
+ '.chat-tool-msg-summary:not(.cl-remote-agent-host-shell *)',
83
+ '.chat-tools-summary:not(.cl-remote-agent-host-shell *)',
84
+ '.tool-card__header',
85
+ '.tool-card__title',
86
+ ],
87
+ indentSelectors: [
88
+ '.chat-group.tool:not(:has(.cl-remote-agent-card))',
89
+ '.chat-bubble:not(:has(.cl-remote-agent-card))',
90
+ ],
91
+ },
92
+ selectors: {
93
+ textContext: '.chat-text, .chat-tool-card__detail, .chat-tool-msg-body, .chat-tools-collapse__body',
94
+ summary: ':scope > summary, :scope > .chat-tools-summary, :scope > .chat-tool-msg-summary, .chat-tools-summary, .chat-tool-msg-summary',
95
+ forceOpenHeader: '.chat-tool-msg-summary, .chat-tools-summary',
96
+ rawTextHostClosest: [
97
+ '.chat-tools-collapse__body',
98
+ '.chat-tool-msg-body',
99
+ '.chat-tool-card__detail',
100
+ '.chat-bubble',
101
+ ],
102
+ rawTextHostsWithinShell: '.chat-tools-collapse__body, .chat-tool-msg-body, .chat-tool-card__detail, .chat-bubble',
103
+ },
104
+ isRemoteNativeToolShellCandidate: function(node) {
105
+ return _matches(node, 'details.chat-tools-collapse, details.chat-tool-msg-collapse, .chat-tools-collapse, .chat-tool-msg-collapse, .chat-tool-card');
106
+ },
107
+ isNativeToolShell: function(node) {
108
+ return _matches(node, 'details.chat-tools-collapse, details.chat-tool-msg-collapse, .chat-tools-collapse, .chat-tool-msg-collapse');
109
+ },
110
+ isToolLikeShell: function(node) {
111
+ return _matches(node, 'details.chat-tools-collapse, details.chat-tool-msg-collapse, .chat-tools-collapse, .chat-tool-msg-collapse, .chat-tool-card, .chat-tools-collapse__body, .chat-tool-msg-body, .chat-tool-card__detail');
112
+ },
113
+ isToolBody: function(node) {
114
+ return _matches(node, '.chat-tools-collapse__body, .chat-tool-msg-body');
115
+ },
116
+ isMarkableHost: function(node) {
117
+ return _matches(node, 'details.chat-tools-collapse, details.chat-tool-msg-collapse, .chat-tool-card, .chat-tool-card__detail, .chat-tools-collapse__body, .chat-tool-msg-body');
118
+ },
119
+ };
120
+
121
+ CL.hostAdapter = adapter;
122
+ try {
123
+ document.documentElement.setAttribute('data-openagent-host-adapter', adapter.id);
124
+ } catch (e) {}
125
+ })();
@@ -0,0 +1,48 @@
1
+ // ── Unknown OpenClaw host adapter ──
2
+ // Fail closed: render OpenAgent's own card, but do not apply host-structure
3
+ // takeover selectors when the host version is not one of the supported series.
4
+
5
+ (function _clInstallHostAdapterUnknown() {
6
+ function _false() { return false; }
7
+
8
+ var adapter = {
9
+ id: 'oc-unknown',
10
+ family: 'unknown',
11
+ css: {
12
+ remoteShell: [],
13
+ outputHostMargin: [],
14
+ outputHostMarginReset: [],
15
+ summaryHidden: [],
16
+ hostShellRawText: [],
17
+ rawTextCardHosts: [],
18
+ rawTextPlaceholderHosts: [],
19
+ hostBody: [],
20
+ manualOpenReset: [],
21
+ hostShellReset: [],
22
+ hostShellSummary: [],
23
+ modernCardLayout: false,
24
+ },
25
+ nativeStyle: {
26
+ shellSelectors: [],
27
+ summarySelectors: [],
28
+ indentSelectors: [],
29
+ },
30
+ selectors: {
31
+ textContext: '.chat-text',
32
+ summary: '',
33
+ forceOpenHeader: '',
34
+ rawTextHostClosest: [],
35
+ rawTextHostsWithinShell: '',
36
+ },
37
+ isRemoteNativeToolShellCandidate: _false,
38
+ isNativeToolShell: _false,
39
+ isToolLikeShell: _false,
40
+ isToolBody: _false,
41
+ isMarkableHost: _false,
42
+ };
43
+
44
+ CL.hostAdapter = adapter;
45
+ try {
46
+ document.documentElement.setAttribute('data-openagent-host-adapter', adapter.id);
47
+ } catch (e) {}
48
+ })();