openclaw-openagent 1.0.11 → 1.0.13

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 (65) hide show
  1. package/dist/index.js +3 -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/config/config-schema.d.ts +9 -0
  5. package/dist/src/config/config-schema.js +6 -0
  6. package/dist/src/plugin-ui/adapters/adapters/oc-2026-04.js +103 -0
  7. package/dist/src/plugin-ui/adapters/adapters/oc-2026-05.js +125 -0
  8. package/dist/src/plugin-ui/adapters/adapters/oc-2026-06.js +125 -0
  9. package/dist/src/plugin-ui/adapters/adapters/oc-unknown.js +48 -0
  10. package/dist/src/plugin-ui/adapters/oc-2026-04.js +103 -0
  11. package/dist/src/plugin-ui/adapters/oc-2026-05.js +125 -0
  12. package/dist/src/plugin-ui/adapters/oc-2026-06.js +125 -0
  13. package/dist/src/plugin-ui/adapters/oc-unknown.js +48 -0
  14. package/dist/src/plugin-ui/assets/openagent-override.js +1129 -273
  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 +75 -8
  20. package/dist/src/plugin-ui/ui-extension-loader/types.d.ts +4 -1
  21. package/dist/src/proxy/auth-proxy.js +5 -0
  22. package/dist/src/runtime/update-checker.d.ts +18 -0
  23. package/dist/src/runtime/update-checker.js +253 -0
  24. package/dist/src/state/store.d.ts +21 -0
  25. package/dist/src/state/store.js +54 -0
  26. package/dist/src/transport/oasn/oasn-invocation.d.ts +3 -0
  27. package/dist/src/transport/oasn/oasn-invocation.js +28 -12
  28. package/dist/src/transport/oasn/oasn-types.d.ts +8 -4
  29. package/index.ts +4 -1
  30. package/package.json +4 -3
  31. package/src/app/remote-agent-tool.ts +131 -16
  32. package/src/app/types.ts +2 -2
  33. package/src/config/config-schema.ts +6 -0
  34. package/src/plugin-ui/adapters/oc-2026-04.js +103 -0
  35. package/src/plugin-ui/adapters/oc-2026-05.js +125 -0
  36. package/src/plugin-ui/adapters/oc-2026-06.js +125 -0
  37. package/src/plugin-ui/adapters/oc-unknown.js +48 -0
  38. package/src/plugin-ui/assets/openagent-override.js +1129 -273
  39. package/src/plugin-ui/build.cjs +249 -38
  40. package/src/plugin-ui/index.ts +2 -2
  41. package/src/plugin-ui/modules/agent-book/panel/agent-book.js +102 -12
  42. package/src/plugin-ui/modules/agent-book/panel/inject-ui.js +105 -3
  43. package/src/plugin-ui/modules/agent-book/panel/styles.js +54 -48
  44. package/src/plugin-ui/modules/agent-book/remote-agent-tool/components-core.js +4 -2
  45. package/src/plugin-ui/modules/agent-book/remote-agent-tool/thought-chain-card.js +4 -1
  46. package/src/plugin-ui/modules/agent-book/scanner.js +17 -5
  47. package/src/plugin-ui/modules/agent-book/travelcard/travel-styles.js +12 -1
  48. package/src/plugin-ui/modules/loader/bootstrap.js +95 -0
  49. package/src/plugin-ui/modules/loader/shared-state.js +244 -20
  50. package/src/plugin-ui/modules/remote-agent/execution-card.js +54 -16
  51. package/src/plugin-ui/modules/remote-agent/native-style-adapter.js +5 -23
  52. package/src/plugin-ui/modules/remote-agent/output-card.js +13 -7
  53. package/src/plugin-ui/modules/remote-agent/render-hooks.js +53 -41
  54. package/src/plugin-ui/modules/remote-agent/styles.js +238 -89
  55. package/src/plugin-ui/modules/remote-agent/tool-card-model.js +72 -4
  56. package/src/plugin-ui/postinstall-deploy.cjs +52 -0
  57. package/src/plugin-ui/ui-extension-loader/index.ts +6 -6
  58. package/src/plugin-ui/ui-extension-loader/registry-regex.ts +81 -9
  59. package/src/plugin-ui/ui-extension-loader/types.ts +5 -1
  60. package/src/proxy/auth-proxy.ts +5 -0
  61. package/src/runtime/update-checker.ts +286 -0
  62. package/src/state/store.ts +80 -0
  63. package/src/transport/oasn/oasn-invocation.ts +47 -12
  64. package/src/transport/oasn/oasn-types.ts +6 -2
  65. package/src/types/openclaw-plugin-sdk-media-store.d.ts +9 -0
@@ -288,15 +288,7 @@ export class OasnInvocation {
288
288
  webuiContinuation,
289
289
  };
290
290
  }
291
- // 失败/超时/取消 —— 文本统一用 user_error.message 兜底
292
- const userError = final.userError ?? final.user_error;
293
- const inlineResult = final.inlineResult ?? final.inline_result;
294
- const visible = final.visibleResult ?? final.visible_result;
295
- const message = userError?.message
296
- ?? inlineResult?.summary
297
- ?? visible?.inlineResultSummary
298
- ?? visible?.inline_result_summary
299
- ?? `Invocation ended with status=${final.status}`;
291
+ const message = this._invocationFailureMessage(final, `Invocation ended with status=${final.status}`);
300
292
  return {
301
293
  requestId: invocationId,
302
294
  status: 'error',
@@ -328,14 +320,38 @@ export class OasnInvocation {
328
320
  }
329
321
  /** 终态错误专用 TransportError,便于上层 catch */
330
322
  _terminalError(final, handle) {
331
- const userError = final.userError ?? final.user_error;
332
- const code = userError?.code ?? `INVOCATION_${final.status.toUpperCase()}`;
333
- const msg = userError?.message ?? `Invocation ${final.status}`;
323
+ const code = this._invocationFailureCode(final) ?? `INVOCATION_${final.status.toUpperCase()}`;
324
+ const msg = this._invocationFailureMessage(final, `Invocation ${final.status}`);
334
325
  return makeTransportError(code, msg, {
335
326
  invocationId: handle.invocationId,
336
327
  sessionId: handle.sessionId,
337
328
  });
338
329
  }
330
+ _invocationFailureCode(final) {
331
+ return this._firstText(final.userError?.code, final.user_error?.code, final.userErrorCode, final.user_error_code);
332
+ }
333
+ _invocationFailureMessage(final, fallback) {
334
+ const userMessage = this._firstText(final.userError?.message, final.user_error?.message, final.userErrorMessage, final.user_error_message);
335
+ if (userMessage)
336
+ return userMessage;
337
+ const inlineResult = final.inlineResult ?? final.inline_result;
338
+ const visible = final.visibleResult ?? final.visible_result;
339
+ const fallbackMessage = this._firstText(inlineResult?.summary, visible?.inlineResultSummary, visible?.inline_result_summary, final.progress?.safeStatusMessage, final.progress?.safe_status_message);
340
+ const code = this._invocationFailureCode(final);
341
+ if (fallbackMessage && code && !fallbackMessage.includes(code))
342
+ return `${fallbackMessage} (${code})`;
343
+ return fallbackMessage ?? code ?? fallback;
344
+ }
345
+ _firstText(...values) {
346
+ for (const value of values) {
347
+ if (typeof value !== 'string')
348
+ continue;
349
+ const trimmed = value.trim();
350
+ if (trimmed)
351
+ return trimmed;
352
+ }
353
+ return undefined;
354
+ }
339
355
  _toArtifactRef(art) {
340
356
  return {
341
357
  id: art.artifactId ?? art.artifact_id ?? '',
@@ -272,13 +272,17 @@ export interface GetInvocationResponse {
272
272
  next_poll_after_ms?: number | null;
273
273
  warnings?: string[];
274
274
  userError?: {
275
- code: string;
276
- message: string;
275
+ code?: string;
276
+ message?: string | null;
277
277
  };
278
278
  user_error?: {
279
- code: string;
280
- message: string;
279
+ code?: string;
280
+ message?: string | null;
281
281
  };
282
+ userErrorCode?: string;
283
+ user_error_code?: string;
284
+ userErrorMessage?: string | null;
285
+ user_error_message?: string | null;
282
286
  createdAt?: string;
283
287
  created_at?: string;
284
288
  updatedAt?: string;
package/index.ts CHANGED
@@ -17,6 +17,7 @@ import { registerTools, registerHooks } from './src/app/index.js';
17
17
  import { installOpenagentVerbosePreflight } from './src/app/verbose-preflight.js';
18
18
  // guard.ts removed — unhandled rejections fixed at source in ws-frame.ts send()
19
19
  import { setOpenagentPluginRuntime } from './src/runtime/plugin-runtime.js';
20
+ import { startOpenagentUpdateChecker } from './src/runtime/update-checker.js';
20
21
  import { injectControlUiOverride } from './src/plugin-ui/index.js';
21
22
  import { createAuthProxyHandler } from './src/proxy/auth-proxy.js';
22
23
  import { logger } from './src/util/logger.js';
@@ -118,10 +119,12 @@ export default {
118
119
  }
119
120
 
120
121
  // Auto-inject Control UI override (copies openagent-override.js + patches)
121
- injectControlUiOverride().catch(err => {
122
+ injectControlUiOverride(api.runtime?.version).catch(err => {
122
123
  logger.warn(`[entry] Control UI injection failed: ${(err as Error).message}`);
123
124
  });
124
125
 
126
+ startOpenagentUpdateChecker();
127
+
125
128
  logger.info('[entry] Tools + hooks registered (full mode)');
126
129
  _fullModeRegistered = true;
127
130
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-openagent",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "type": "module",
5
5
  "description": "OpenAgent channel plugin for OpenClaw",
6
6
  "license": "MIT",
@@ -47,9 +47,10 @@
47
47
  "node": ">=22"
48
48
  },
49
49
  "scripts": {
50
- "build": "tsc -p tsconfig.build.json && cp -r src/sdk dist/src/sdk && mkdir -p dist/src/plugin-ui/assets && cp src/plugin-ui/assets/openagent-override.js src/plugin-ui/assets/icon.png src/plugin-ui/assets/bg.png dist/src/plugin-ui/assets/",
50
+ "build": "tsc -p tsconfig.build.json && cp -r src/sdk dist/src/sdk && mkdir -p dist/src/plugin-ui/assets && cp src/plugin-ui/assets/openagent-override.js src/plugin-ui/assets/icon.png src/plugin-ui/assets/bg.png dist/src/plugin-ui/assets/ && cp -r src/plugin-ui/adapters dist/src/plugin-ui/adapters",
51
51
  "build:override": "node ./src/plugin-ui/build.cjs",
52
52
  "watch:override": "node ./src/plugin-ui/build.cjs --watch",
53
+ "postinstall": "node ./src/plugin-ui/postinstall-deploy.cjs",
53
54
  "prepack": "npm run build:override && npm run build && npm run typecheck",
54
55
  "typecheck": "tsc --noEmit",
55
56
  "prepublishOnly": "npm run typecheck",
@@ -75,7 +76,7 @@
75
76
  "@types/node": "^25.5.0",
76
77
  "@types/sql.js": "^1.4.11",
77
78
  "@types/yazl": "^3.3.1",
78
- "openclaw": "^2026.6.10",
79
+ "openclaw": "2026.4.22",
79
80
  "tsx": "^4.21.0",
80
81
  "typescript": "^6.0.2"
81
82
  }
@@ -206,14 +206,20 @@ function formatMediaDownloadLines(urls: string[]): string {
206
206
  function normalizeRemoteToolExecuteArgs(
207
207
  signalOrUpdate?: AbortSignal | ToolUpdateCallback,
208
208
  onUpdateOrContext?: ToolUpdateCallback | unknown,
209
- legacySignal?: AbortSignal,
210
- ): { signal?: AbortSignal; onUpdate?: ToolUpdateCallback; signature: string } {
209
+ contextOrSignal?: unknown,
210
+ ): { signal?: AbortSignal; onUpdate?: ToolUpdateCallback; context?: unknown; signature: string } {
211
+ const contextCandidate = (value: unknown): unknown | undefined => {
212
+ if (!value || typeof value !== 'object' || isAbortSignalLike(value)) return undefined;
213
+ return value;
214
+ };
215
+
211
216
  if (typeof signalOrUpdate === 'function') {
212
217
  return {
213
218
  onUpdate: signalOrUpdate,
214
- signal: isAbortSignalLike(legacySignal)
215
- ? legacySignal
219
+ signal: isAbortSignalLike(contextOrSignal)
220
+ ? contextOrSignal
216
221
  : getObjectSignal(onUpdateOrContext),
222
+ context: contextCandidate(onUpdateOrContext),
217
223
  signature: 'legacy:update-third',
218
224
  };
219
225
  }
@@ -222,7 +228,8 @@ function normalizeRemoteToolExecuteArgs(
222
228
  return {
223
229
  signal: isAbortSignalLike(signalOrUpdate) ? signalOrUpdate : undefined,
224
230
  onUpdate: onUpdateOrContext as ToolUpdateCallback,
225
- signature: 'modern:signal-update',
231
+ context: contextCandidate(contextOrSignal),
232
+ signature: contextCandidate(contextOrSignal) ? 'modern:signal-update-context' : 'modern:signal-update',
226
233
  };
227
234
  }
228
235
 
@@ -233,15 +240,108 @@ function normalizeRemoteToolExecuteArgs(
233
240
  const nestedSignal =
234
241
  isAbortSignalLike(signalOrUpdate)
235
242
  ? signalOrUpdate
236
- : getObjectSignal(onUpdateOrContext) || (isAbortSignalLike(legacySignal) ? legacySignal : undefined);
243
+ : getObjectSignal(onUpdateOrContext) || (isAbortSignalLike(contextOrSignal) ? contextOrSignal : undefined);
237
244
 
238
245
  return {
239
246
  signal: nestedSignal,
240
247
  onUpdate: nestedUpdate,
248
+ context: contextCandidate(contextOrSignal) || contextCandidate(onUpdateOrContext),
241
249
  signature: nestedUpdate ? 'context:update-callback' : 'unknown:no-update',
242
250
  };
243
251
  }
244
252
 
253
+ function readNonEmptyString(value: unknown): string | undefined {
254
+ return typeof value === 'string' && value.trim() ? value.trim() : undefined;
255
+ }
256
+
257
+ function readRecord(value: unknown): Record<string, unknown> | undefined {
258
+ return value && typeof value === 'object' ? value as Record<string, unknown> : undefined;
259
+ }
260
+
261
+ function callStringGetter(target: unknown, methodName: string): string | undefined {
262
+ const record = readRecord(target);
263
+ const fn = record?.[methodName];
264
+ if (typeof fn !== 'function') return undefined;
265
+ try {
266
+ return readNonEmptyString(fn.call(target));
267
+ } catch {
268
+ return undefined;
269
+ }
270
+ }
271
+
272
+ function readNestedString(root: unknown, path: string[]): string | undefined {
273
+ let cur: unknown = root;
274
+ for (const key of path) {
275
+ const record = readRecord(cur);
276
+ if (!record) return undefined;
277
+ cur = record[key];
278
+ }
279
+ return readNonEmptyString(cur);
280
+ }
281
+
282
+ function resolveOpenclawSessionKey(context: unknown): string | undefined {
283
+ const ctx = readRecord(context);
284
+ if (!ctx) return undefined;
285
+
286
+ const sessionManager = ctx.sessionManager;
287
+ const managerSessionId = callStringGetter(sessionManager, 'getSessionId');
288
+ if (managerSessionId) return `session:${managerSessionId}`;
289
+
290
+ const directSessionId =
291
+ readNonEmptyString(ctx.sessionId) ||
292
+ readNonEmptyString(ctx.openclawSessionId) ||
293
+ readNonEmptyString(ctx.agentSessionId) ||
294
+ readNestedString(ctx, ['session', 'sessionId']);
295
+ if (directSessionId) return `session:${directSessionId}`;
296
+
297
+ const sessionFile =
298
+ callStringGetter(sessionManager, 'getSessionFile') ||
299
+ readNestedString(ctx, ['session', 'sessionFile']);
300
+ if (sessionFile) return `file:${sessionFile}`;
301
+
302
+ return undefined;
303
+ }
304
+
305
+ function getRememberedRemoteSessionId(
306
+ runtime: { store?: { getRemoteAgentSession?: (openclawSessionKey: string, targetAgentId: string) => string | null } | null },
307
+ openclawSessionKey: string | undefined,
308
+ agentId: string,
309
+ ): string | undefined {
310
+ if (!openclawSessionKey) return undefined;
311
+ try {
312
+ return runtime.store?.getRemoteAgentSession?.(openclawSessionKey, agentId) || undefined;
313
+ } catch (err) {
314
+ logger.warn(`[remote-tool] Failed to read remembered OASN session: ${(err as Error).message}`);
315
+ return undefined;
316
+ }
317
+ }
318
+
319
+ function rememberRemoteSessionId(
320
+ runtime: {
321
+ store?: {
322
+ upsertRemoteAgentSession?: (record: {
323
+ openclaw_session_key: string;
324
+ target_agent_id: string;
325
+ session_id: string;
326
+ }) => void;
327
+ } | null;
328
+ },
329
+ openclawSessionKey: string | undefined,
330
+ agentId: string,
331
+ sessionId: string | undefined,
332
+ ): void {
333
+ if (!openclawSessionKey || !sessionId) return;
334
+ try {
335
+ runtime.store?.upsertRemoteAgentSession?.({
336
+ openclaw_session_key: openclawSessionKey,
337
+ target_agent_id: agentId,
338
+ session_id: sessionId,
339
+ });
340
+ } catch (err) {
341
+ logger.warn(`[remote-tool] Failed to remember OASN session: ${(err as Error).message}`);
342
+ }
343
+ }
344
+
245
345
  // ── Tool Factory ──
246
346
 
247
347
  /**
@@ -259,9 +359,9 @@ export function createCallRemoteAgentTool(): ToolDescriptor {
259
359
  label: 'Call Remote Agent',
260
360
  description:
261
361
  'Route a user request to a remote specialist Agent via the OpenAgent network. ' +
262
- 'TRIGGER: When the user message contains a {openagent_call_remote_agent:agent_id="...",agent_name="...",instruction="..."} marker, ' +
362
+ 'TRIGGER: When the user message contains a {openagent_call_remote_agent:agent_id="...",agent_name="...",agent_bio="...",instruction="..."} marker, ' +
263
363
  'call this tool to forward the request to the specified remote Agent. ' +
264
- 'Extract agent_id and agent_name from the marker; use the remaining natural-language text as the task parameter. ' +
364
+ 'Extract agent_id, agent_name, and optional agent_bio from the marker; use the remaining natural-language text as the task parameter. ' +
265
365
  'Do not display the raw marker to the user. ' +
266
366
  'mode "session" (default) preserves remote conversation history; mode "run" starts fresh — include full context in task.',
267
367
  parameters: {
@@ -275,6 +375,10 @@ export function createCallRemoteAgentTool(): ToolDescriptor {
275
375
  type: 'string',
276
376
  description: 'Display name of the remote Agent from the marker. Use this in your reply to the user.',
277
377
  },
378
+ agent_bio: {
379
+ type: 'string',
380
+ description: 'Short description of the remote Agent from the marker. Preserve it for UI display.',
381
+ },
278
382
  task: {
279
383
  type: 'string',
280
384
  description: 'The user\'s natural-language request text, excluding the marker.',
@@ -303,18 +407,18 @@ export function createCallRemoteAgentTool(): ToolDescriptor {
303
407
  params: ToolParams,
304
408
  signalOrUpdate?: AbortSignal | ToolUpdateCallback,
305
409
  onUpdateOrContext?: ToolUpdateCallback | unknown,
306
- legacySignal?: AbortSignal,
410
+ contextOrSignal?: unknown,
307
411
  ): Promise<ToolResult> {
308
- const { signal, onUpdate, signature } = normalizeRemoteToolExecuteArgs(
412
+ const { signal, onUpdate, context, signature } = normalizeRemoteToolExecuteArgs(
309
413
  signalOrUpdate,
310
414
  onUpdateOrContext,
311
- legacySignal,
415
+ contextOrSignal,
312
416
  );
313
417
  logger.info(
314
418
  `[remote-tool] Execute args: toolCallId=${String(_id)} signature=${signature} ` +
315
419
  `hasSignal=${Boolean(signal)} hasOnUpdate=${Boolean(onUpdate)} ` +
316
420
  `third=${describeExecuteArg(signalOrUpdate)} fourth=${describeExecuteArg(onUpdateOrContext)} ` +
317
- `fifth=${describeExecuteArg(legacySignal)}`,
421
+ `fifth=${describeExecuteArg(contextOrSignal)}`,
318
422
  );
319
423
 
320
424
  // ① Check runtime (same pattern as messaging-tools.ts)
@@ -334,7 +438,7 @@ export function createCallRemoteAgentTool(): ToolDescriptor {
334
438
 
335
439
  const agentId = String(params.agent_id || '').trim();
336
440
  const task = String(params.task || '').trim();
337
- const mode = String(params.mode || 'session').trim();
441
+ const mode = String(params.mode || 'session').trim() === 'run' ? 'run' : 'session';
338
442
 
339
443
  // ② Validate required params
340
444
  if (!agentId) {
@@ -402,15 +506,20 @@ export function createCallRemoteAgentTool(): ToolDescriptor {
402
506
  const inputFileRefs: string[] | undefined = Array.isArray(params.input_file_refs)
403
507
  ? (params.input_file_refs as string[]).filter((r: unknown) => typeof r === 'string' && r.trim())
404
508
  : undefined;
509
+ const openclawSessionKey = resolveOpenclawSessionKey(context);
510
+ const rememberedSessionId = mode === 'session'
511
+ ? getRememberedRemoteSessionId(rt, openclawSessionKey, agentId)
512
+ : undefined;
513
+ if (mode === 'session' && !openclawSessionKey) {
514
+ logger.warn('[remote-tool] OASN session mode requested but OpenClaw session scope is unavailable');
515
+ }
405
516
 
406
517
  const taskReq: TaskRequest = {
407
518
  requestId,
408
519
  task,
520
+ sessionId: rememberedSessionId,
409
521
  inputFileRefs: inputFileRefs?.length ? inputFileRefs : undefined,
410
522
  timeoutMs: OASN_INVOCATION_TIMEOUT_MS,
411
- // mode='session' 时不在协议层 join 已有 session(OASN 默认每次起新 Invocation)。
412
- // 上游若需要保留对话历史,请在 task 文本里显式带 session_id;
413
- // 暂不在工具层做 session 续传,避免误用导致跨用户串号。
414
523
  };
415
524
 
416
525
  let handle: TaskHandle;
@@ -424,6 +533,9 @@ export function createCallRemoteAgentTool(): ToolDescriptor {
424
533
  `[remote-tool] OASN invocation created: invocationId=${handle.invocationId} ` +
425
534
  `sessionId=${handle.sessionId ?? '-'} effectiveTimeoutMs=${handle.effectiveTimeoutMs ?? '-'}`,
426
535
  );
536
+ if (mode === 'session') {
537
+ rememberRemoteSessionId(rt, openclawSessionKey, agentId, handle.sessionId);
538
+ }
427
539
 
428
540
  try {
429
541
  const result = await oasnTransport.waitForTaskResult(handle, {
@@ -435,6 +547,9 @@ export function createCallRemoteAgentTool(): ToolDescriptor {
435
547
  const artifacts = result.artifacts ?? [];
436
548
  let content = result.content;
437
549
  let mediaUrls: string[] = [];
550
+ if (mode === 'session') {
551
+ rememberRemoteSessionId(rt, openclawSessionKey, agentId, result.webuiContinuation?.sessionId);
552
+ }
438
553
 
439
554
  if (!content.trim()) {
440
555
  for (const textArtifact of artifacts) {
package/src/app/types.ts CHANGED
@@ -41,7 +41,7 @@ export interface ToolDescriptor {
41
41
  * Execute the tool.
42
42
  *
43
43
  * OpenClaw runtime usually calls:
44
- * tool.execute(toolCallId, params, signal, onUpdate)
44
+ * tool.execute(toolCallId, params, signal, onUpdate, ctx)
45
45
  *
46
46
  * Older adapters used:
47
47
  * tool.execute(toolCallId, params, onUpdate, ctx, signal)
@@ -56,7 +56,7 @@ export interface ToolDescriptor {
56
56
  params: ToolParams,
57
57
  signalOrUpdate?: AbortSignal | ToolUpdateCallback,
58
58
  onUpdateOrContext?: ToolUpdateCallback | unknown,
59
- legacySignal?: AbortSignal,
59
+ contextOrSignal?: unknown,
60
60
  ) => Promise<ToolResult>;
61
61
  }
62
62
 
@@ -16,6 +16,7 @@ import { z } from 'zod';
16
16
  // ---------------------------------------------------------------------------
17
17
 
18
18
  const transportSchema = z.enum(['oasn', 'tim']).default('oasn');
19
+ const updatePolicySchema = z.enum(['notify', 'auto', 'off']).optional();
19
20
 
20
21
  const openagentAccountSchema = z.object({
21
22
  name: z.string().optional(),
@@ -35,5 +36,10 @@ export const OpenagentConfigSchema = openagentAccountSchema.extend({
35
36
  transport: transportSchema.optional(),
36
37
  api_base: z.string().optional(),
37
38
  access_api_base: z.string().optional(),
39
+ update_policy: updatePolicySchema,
40
+ update_check: z.boolean().optional(),
41
+ auto_update: z.boolean().optional(),
42
+ update_channel: z.string().optional(),
43
+ update_dist_tag: z.string().optional(),
38
44
  accounts: z.record(z.string(), openagentAccountSchema).optional(),
39
45
  });
@@ -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
+ })();