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.
- package/dist/index.js +3 -1
- package/dist/src/app/remote-agent-tool.js +110 -14
- package/dist/src/app/types.d.ts +2 -2
- package/dist/src/config/config-schema.d.ts +9 -0
- package/dist/src/config/config-schema.js +6 -0
- package/dist/src/plugin-ui/adapters/adapters/oc-2026-04.js +103 -0
- package/dist/src/plugin-ui/adapters/adapters/oc-2026-05.js +125 -0
- package/dist/src/plugin-ui/adapters/adapters/oc-2026-06.js +125 -0
- package/dist/src/plugin-ui/adapters/adapters/oc-unknown.js +48 -0
- package/dist/src/plugin-ui/adapters/oc-2026-04.js +103 -0
- package/dist/src/plugin-ui/adapters/oc-2026-05.js +125 -0
- package/dist/src/plugin-ui/adapters/oc-2026-06.js +125 -0
- package/dist/src/plugin-ui/adapters/oc-unknown.js +48 -0
- package/dist/src/plugin-ui/assets/openagent-override.js +1129 -273
- package/dist/src/plugin-ui/index.d.ts +1 -1
- package/dist/src/plugin-ui/index.js +2 -2
- package/dist/src/plugin-ui/ui-extension-loader/index.d.ts +2 -1
- package/dist/src/plugin-ui/ui-extension-loader/index.js +5 -5
- package/dist/src/plugin-ui/ui-extension-loader/registry-regex.js +75 -8
- package/dist/src/plugin-ui/ui-extension-loader/types.d.ts +4 -1
- package/dist/src/proxy/auth-proxy.js +5 -0
- package/dist/src/runtime/update-checker.d.ts +18 -0
- package/dist/src/runtime/update-checker.js +253 -0
- package/dist/src/state/store.d.ts +21 -0
- package/dist/src/state/store.js +54 -0
- package/dist/src/transport/oasn/oasn-invocation.d.ts +3 -0
- package/dist/src/transport/oasn/oasn-invocation.js +28 -12
- package/dist/src/transport/oasn/oasn-types.d.ts +8 -4
- package/index.ts +4 -1
- package/package.json +4 -3
- package/src/app/remote-agent-tool.ts +131 -16
- package/src/app/types.ts +2 -2
- package/src/config/config-schema.ts +6 -0
- package/src/plugin-ui/adapters/oc-2026-04.js +103 -0
- package/src/plugin-ui/adapters/oc-2026-05.js +125 -0
- package/src/plugin-ui/adapters/oc-2026-06.js +125 -0
- package/src/plugin-ui/adapters/oc-unknown.js +48 -0
- package/src/plugin-ui/assets/openagent-override.js +1129 -273
- package/src/plugin-ui/build.cjs +249 -38
- package/src/plugin-ui/index.ts +2 -2
- package/src/plugin-ui/modules/agent-book/panel/agent-book.js +102 -12
- package/src/plugin-ui/modules/agent-book/panel/inject-ui.js +105 -3
- package/src/plugin-ui/modules/agent-book/panel/styles.js +54 -48
- package/src/plugin-ui/modules/agent-book/remote-agent-tool/components-core.js +4 -2
- package/src/plugin-ui/modules/agent-book/remote-agent-tool/thought-chain-card.js +4 -1
- package/src/plugin-ui/modules/agent-book/scanner.js +17 -5
- package/src/plugin-ui/modules/agent-book/travelcard/travel-styles.js +12 -1
- package/src/plugin-ui/modules/loader/bootstrap.js +95 -0
- package/src/plugin-ui/modules/loader/shared-state.js +244 -20
- package/src/plugin-ui/modules/remote-agent/execution-card.js +54 -16
- package/src/plugin-ui/modules/remote-agent/native-style-adapter.js +5 -23
- package/src/plugin-ui/modules/remote-agent/output-card.js +13 -7
- package/src/plugin-ui/modules/remote-agent/render-hooks.js +53 -41
- package/src/plugin-ui/modules/remote-agent/styles.js +238 -89
- package/src/plugin-ui/modules/remote-agent/tool-card-model.js +72 -4
- package/src/plugin-ui/postinstall-deploy.cjs +52 -0
- package/src/plugin-ui/ui-extension-loader/index.ts +6 -6
- package/src/plugin-ui/ui-extension-loader/registry-regex.ts +81 -9
- package/src/plugin-ui/ui-extension-loader/types.ts +5 -1
- package/src/proxy/auth-proxy.ts +5 -0
- package/src/runtime/update-checker.ts +286 -0
- package/src/state/store.ts +80 -0
- package/src/transport/oasn/oasn-invocation.ts +47 -12
- package/src/transport/oasn/oasn-types.ts +6 -2
- 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
|
-
|
|
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
|
|
332
|
-
const
|
|
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
|
|
276
|
-
message
|
|
275
|
+
code?: string;
|
|
276
|
+
message?: string | null;
|
|
277
277
|
};
|
|
278
278
|
user_error?: {
|
|
279
|
-
code
|
|
280
|
-
message
|
|
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.
|
|
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": "
|
|
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
|
-
|
|
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(
|
|
215
|
-
?
|
|
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
|
-
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
+
})();
|