@xfxstudio/claworld 0.2.9 → 0.2.10-beta.1
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/README.md +1 -1
- package/openclaw.plugin.json +7 -63
- package/package.json +6 -2
- package/skills/claworld-help/SKILL.md +5 -1
- package/skills/claworld-join-and-chat/SKILL.md +21 -1
- package/skills/claworld-manage-worlds/SKILL.md +81 -10
- package/src/lib/agent-profile.js +8 -3
- package/src/lib/chat-request.js +0 -1
- package/src/lib/policy.js +2 -6
- package/src/lib/public-identity.js +175 -0
- package/src/lib/relay/kickoff-text.js +1 -0
- package/src/openclaw/installer/cli.js +48 -4
- package/src/openclaw/installer/constants.js +1 -0
- package/src/openclaw/installer/core.js +247 -71
- package/src/openclaw/installer/doctor.js +31 -17
- package/src/openclaw/plugin/account-identity.js +1 -2
- package/src/openclaw/plugin/claworld-channel-plugin.js +453 -263
- package/src/openclaw/plugin/config-schema.js +9 -23
- package/src/openclaw/plugin/managed-config.js +294 -84
- package/src/openclaw/plugin/onboarding.js +37 -45
- package/src/openclaw/plugin/register.js +124 -13
- package/src/openclaw/plugin/relay-client.js +233 -17
- package/src/openclaw/runtime/backend-error-context.js +91 -0
- package/src/openclaw/runtime/feedback-helper.js +1 -2
- package/src/openclaw/runtime/product-shell-helper.js +43 -9
- package/src/openclaw/runtime/tool-contracts.js +26 -3
- package/src/openclaw/runtime/tool-inventory.js +7 -0
- package/src/openclaw/runtime/world-moderation-helper.js +3 -19
- package/src/product-shell/contracts/candidate-feed.js +7 -0
- package/src/product-shell/contracts/world-manifest.js +0 -1
- package/src/product-shell/contracts/world-orchestration.js +10 -1
- package/src/product-shell/conversation-feedback/conversation-feedback-service.js +261 -0
- package/src/product-shell/feedback/feedback-routes.js +0 -1
- package/src/product-shell/feedback/feedback-service.js +4 -9
- package/src/product-shell/index.js +40 -7
- package/src/product-shell/matching/matchmaking-service.js +22 -1
- package/src/product-shell/membership/membership-service.js +5 -1
- package/src/product-shell/onboarding/onboarding-service.js +16 -26
- package/src/product-shell/profile/public-identity-routes.js +60 -0
- package/src/product-shell/profile/public-identity-service.js +190 -0
- package/src/product-shell/search/search-service.js +9 -2
- package/src/product-shell/social/chat-request-service.js +22 -7
- package/src/product-shell/social/friend-routes.js +1 -1
- package/src/product-shell/social/friend-service.js +16 -19
- package/src/product-shell/social/social-routes.js +2 -2
- package/src/product-shell/social/social-service.js +31 -35
- package/src/product-shell/worlds/world-admin-service.js +31 -10
- package/src/product-shell/worlds/world-broadcast-service.js +2 -2
- package/src/lib/agent-address.js +0 -46
|
@@ -13,8 +13,6 @@ import {
|
|
|
13
13
|
const REQUIRED_KEYS = ['enabled', 'serverUrl', 'apiKey', 'accountId'];
|
|
14
14
|
|
|
15
15
|
export const CLAWORLD_CHANNEL_ID = 'claworld';
|
|
16
|
-
const LOCAL_AGENT_CODE_PATTERN = '^[A-Za-z0-9._:+~-]+(?:@[A-Za-z0-9._:+~-]+)?$';
|
|
17
|
-
const LOCAL_AGENT_CODE_REGEX = new RegExp(LOCAL_AGENT_CODE_PATTERN, 'i');
|
|
18
16
|
|
|
19
17
|
const AGENT_REGISTRATION_SCHEMA = {
|
|
20
18
|
type: 'object',
|
|
@@ -25,22 +23,16 @@ const AGENT_REGISTRATION_SCHEMA = {
|
|
|
25
23
|
description: 'Enable relay agent registration when this account does not already have an app token.',
|
|
26
24
|
default: false,
|
|
27
25
|
},
|
|
28
|
-
agentCode: {
|
|
29
|
-
type: 'string',
|
|
30
|
-
minLength: 1,
|
|
31
|
-
pattern: LOCAL_AGENT_CODE_PATTERN,
|
|
32
|
-
description: 'Unique Claworld identity handle. Accepts raw local code or canonical local@namespace (for example "xiaofafa@robin").',
|
|
33
|
-
},
|
|
34
26
|
displayName: {
|
|
35
27
|
type: 'string',
|
|
36
28
|
minLength: 1,
|
|
37
|
-
description: '
|
|
29
|
+
description: 'Public display name to use when the relay agent is created or refreshed.',
|
|
38
30
|
},
|
|
39
31
|
},
|
|
40
32
|
};
|
|
41
33
|
|
|
42
34
|
export const LOCAL_AGENT_BOOTSTRAP_SCHEMA = AGENT_REGISTRATION_SCHEMA;
|
|
43
|
-
export const LOCAL_AGENT_BOOTSTRAP_REQUIRED = ['
|
|
35
|
+
export const LOCAL_AGENT_BOOTSTRAP_REQUIRED = ['displayName'];
|
|
44
36
|
|
|
45
37
|
export const MANUAL_RELAY_BINDING_SCHEMA = {
|
|
46
38
|
type: 'object',
|
|
@@ -61,10 +53,10 @@ export const MANUAL_RELAY_BINDING_SCHEMA = {
|
|
|
61
53
|
minLength: 1,
|
|
62
54
|
description: 'Legacy alias for appToken.',
|
|
63
55
|
},
|
|
64
|
-
|
|
56
|
+
defaultTargetAgentId: {
|
|
65
57
|
type: 'string',
|
|
66
58
|
minLength: 1,
|
|
67
|
-
description: 'Default relay target
|
|
59
|
+
description: 'Default relay target agentId for minimal outbound testing.',
|
|
68
60
|
},
|
|
69
61
|
},
|
|
70
62
|
};
|
|
@@ -183,7 +175,6 @@ const SINGLE_ACCOUNT_PROPERTIES = {
|
|
|
183
175
|
},
|
|
184
176
|
},
|
|
185
177
|
registration: AGENT_REGISTRATION_SCHEMA,
|
|
186
|
-
localAgent: LOCAL_AGENT_BOOTSTRAP_SCHEMA,
|
|
187
178
|
relay: MANUAL_RELAY_BINDING_SCHEMA,
|
|
188
179
|
};
|
|
189
180
|
|
|
@@ -213,10 +204,10 @@ export const claworldChannelConfigJsonSchema = {
|
|
|
213
204
|
export const claworldChannelConfigSchema = {
|
|
214
205
|
channelId: CLAWORLD_CHANNEL_ID,
|
|
215
206
|
required: REQUIRED_KEYS,
|
|
216
|
-
optional: ['name', 'heartbeatSeconds', 'reconnect', 'routing', 'approval', 'testing', 'appToken', 'registration', '
|
|
207
|
+
optional: ['name', 'heartbeatSeconds', 'reconnect', 'routing', 'approval', 'testing', 'appToken', 'registration', 'relay', 'toolProfile', 'defaultAccount', 'accounts'],
|
|
217
208
|
jsonSchema: claworldChannelConfigJsonSchema,
|
|
218
209
|
description:
|
|
219
|
-
'最小 OpenClaw claworld channel 配置;支持单账号或 accounts.<id> 多账号模式。canonical flow uses appToken + registration
|
|
210
|
+
'最小 OpenClaw claworld channel 配置;支持单账号或 accounts.<id> 多账号模式。canonical flow uses appToken + registration.displayName bootstrap.',
|
|
220
211
|
routingShape: {
|
|
221
212
|
sessionTarget: 'mainagent',
|
|
222
213
|
fallbackTarget: 'mainagent',
|
|
@@ -341,11 +332,8 @@ export function validateClaworldChannelConfig(config = {}, accountId = null) {
|
|
|
341
332
|
errors.push({ code: 'invalid_fallback_target', value: fallbackTarget });
|
|
342
333
|
}
|
|
343
334
|
|
|
344
|
-
if (registration.enabled && !registration.
|
|
345
|
-
errors.push({ code: '
|
|
346
|
-
}
|
|
347
|
-
if (registration.enabled && registration.agentCode && !LOCAL_AGENT_CODE_REGEX.test(String(registration.agentCode).trim())) {
|
|
348
|
-
errors.push({ code: 'invalid_local_agent_code', value: registration.agentCode });
|
|
335
|
+
if (registration.enabled && !registration.displayName) {
|
|
336
|
+
errors.push({ code: 'missing_registration_display_name' });
|
|
349
337
|
}
|
|
350
338
|
|
|
351
339
|
if (candidate.relay?.agentId && !appToken) {
|
|
@@ -375,7 +363,7 @@ export function validateClaworldChannelConfig(config = {}, accountId = null) {
|
|
|
375
363
|
agentId: candidate.relay?.agentId || null,
|
|
376
364
|
appToken,
|
|
377
365
|
credentialToken: appToken,
|
|
378
|
-
|
|
366
|
+
defaultTargetAgentId: candidate.relay?.defaultTargetAgentId || null,
|
|
379
367
|
},
|
|
380
368
|
});
|
|
381
369
|
|
|
@@ -407,7 +395,6 @@ export function inspectClaworldChannelAccount(config = {}, accountId = null) {
|
|
|
407
395
|
testing: normalized.testing,
|
|
408
396
|
appToken: normalized.appToken || null,
|
|
409
397
|
registration: normalized.registration,
|
|
410
|
-
localAgent: normalized.localAgent,
|
|
411
398
|
relay: normalized.relay,
|
|
412
399
|
defaultAccount: normalized.defaultAccount,
|
|
413
400
|
bindingStatus,
|
|
@@ -435,7 +422,6 @@ export function resolveClaworldRuntimeConfig(config = {}, accountId = null) {
|
|
|
435
422
|
...result.normalized,
|
|
436
423
|
accountId: result.normalized.accountId || accountId || readDefaultAccountId(config) || 'default',
|
|
437
424
|
approval: result.normalized.approval,
|
|
438
|
-
localAgent: result.normalized.localAgent,
|
|
439
425
|
relay: result.normalized.relay,
|
|
440
426
|
};
|
|
441
427
|
}
|
|
@@ -25,6 +25,8 @@ export const DEFAULT_CLAWORLD_FALLBACK_TARGET = 'mainagent';
|
|
|
25
25
|
export const CLAWORLD_PLUGIN_TOOL_ALLOW_ENTRY = 'claworld';
|
|
26
26
|
export const MIN_MANAGED_SESSION_VISIBILITY = 'agent';
|
|
27
27
|
export const REQUIRED_SANDBOX_SESSION_TOOLS_VISIBILITY = 'all';
|
|
28
|
+
export const CLAWORLD_INSTALLER_STATE_ROOT_KEY = 'claworldInstaller';
|
|
29
|
+
export const CLAWORLD_MANAGED_RUNTIME_BACKUP_VERSION = 1;
|
|
28
30
|
|
|
29
31
|
export const TOOL_PROFILES = CLAWORLD_TOOL_PROFILES;
|
|
30
32
|
|
|
@@ -49,9 +51,9 @@ export function ensureObject(value) {
|
|
|
49
51
|
return value;
|
|
50
52
|
}
|
|
51
53
|
|
|
52
|
-
function
|
|
54
|
+
function normalizeRegistrationDisplayName(value, fallback = null) {
|
|
53
55
|
const normalized = normalizeText(value, fallback);
|
|
54
|
-
return normalized
|
|
56
|
+
return normalized || fallback;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
export function expandUserPath(input, homeDir = os.homedir()) {
|
|
@@ -103,14 +105,6 @@ function mergeManagedPluginToolExposure(existingTools = {}) {
|
|
|
103
105
|
};
|
|
104
106
|
}
|
|
105
107
|
|
|
106
|
-
function inferRelayDomain(defaultToAddress = null) {
|
|
107
|
-
const normalized = normalizeText(defaultToAddress, null);
|
|
108
|
-
if (!normalized) return 'relay.local';
|
|
109
|
-
const atIndex = normalized.indexOf('@');
|
|
110
|
-
if (atIndex <= 0 || atIndex >= normalized.length - 1) return 'relay.local';
|
|
111
|
-
return normalized.slice(atIndex + 1).trim().toLowerCase() || 'relay.local';
|
|
112
|
-
}
|
|
113
|
-
|
|
114
108
|
function findAgentIndex(agentList = [], agentId) {
|
|
115
109
|
return agentList.findIndex((item) => ensureObject(item).id === agentId);
|
|
116
110
|
}
|
|
@@ -130,6 +124,72 @@ function findManagedAccountEntry(config = {}, accountId) {
|
|
|
130
124
|
return {};
|
|
131
125
|
}
|
|
132
126
|
|
|
127
|
+
function ensureMutableInstallerStateRoot(installerState = {}) {
|
|
128
|
+
installerState[CLAWORLD_INSTALLER_STATE_ROOT_KEY] = ensureObject(installerState[CLAWORLD_INSTALLER_STATE_ROOT_KEY]);
|
|
129
|
+
const rootState = ensureObject(installerState[CLAWORLD_INSTALLER_STATE_ROOT_KEY]);
|
|
130
|
+
rootState.managedRuntime = ensureObject(rootState.managedRuntime);
|
|
131
|
+
rootState.managedRuntime.accounts = ensureObject(rootState.managedRuntime.accounts);
|
|
132
|
+
installerState[CLAWORLD_INSTALLER_STATE_ROOT_KEY] = rootState;
|
|
133
|
+
return rootState.managedRuntime.accounts;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function trimInstallerStateRoot(installerState = {}) {
|
|
137
|
+
const rootState = ensureObject(installerState[CLAWORLD_INSTALLER_STATE_ROOT_KEY]);
|
|
138
|
+
const managedRuntime = ensureObject(rootState.managedRuntime);
|
|
139
|
+
const accounts = ensureObject(managedRuntime.accounts);
|
|
140
|
+
if (Object.keys(accounts).length === 0) {
|
|
141
|
+
delete managedRuntime.accounts;
|
|
142
|
+
} else {
|
|
143
|
+
managedRuntime.accounts = accounts;
|
|
144
|
+
}
|
|
145
|
+
if (Object.keys(managedRuntime).length === 0) {
|
|
146
|
+
delete rootState.managedRuntime;
|
|
147
|
+
} else {
|
|
148
|
+
rootState.managedRuntime = managedRuntime;
|
|
149
|
+
}
|
|
150
|
+
if (Object.keys(rootState).length === 0) {
|
|
151
|
+
delete installerState[CLAWORLD_INSTALLER_STATE_ROOT_KEY];
|
|
152
|
+
} else {
|
|
153
|
+
installerState[CLAWORLD_INSTALLER_STATE_ROOT_KEY] = rootState;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export function findClaworldManagedRuntimeBackup(installerState = {}, accountId = DEFAULT_CLAWORLD_ACCOUNT_ID) {
|
|
158
|
+
const normalizedAccountId = normalizeText(accountId, DEFAULT_CLAWORLD_ACCOUNT_ID);
|
|
159
|
+
const rootState = ensureObject(installerState?.[CLAWORLD_INSTALLER_STATE_ROOT_KEY]);
|
|
160
|
+
const managedRuntime = ensureObject(rootState.managedRuntime);
|
|
161
|
+
const accounts = ensureObject(managedRuntime.accounts);
|
|
162
|
+
return ensureObject(accounts[normalizedAccountId]);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export function setClaworldManagedRuntimeBackupState(
|
|
166
|
+
installerState = {},
|
|
167
|
+
accountId = DEFAULT_CLAWORLD_ACCOUNT_ID,
|
|
168
|
+
value = null,
|
|
169
|
+
) {
|
|
170
|
+
const normalizedAccountId = normalizeText(accountId, DEFAULT_CLAWORLD_ACCOUNT_ID);
|
|
171
|
+
const accounts = ensureMutableInstallerStateRoot(installerState);
|
|
172
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
173
|
+
accounts[normalizedAccountId] = JSON.parse(JSON.stringify(value));
|
|
174
|
+
} else {
|
|
175
|
+
delete accounts[normalizedAccountId];
|
|
176
|
+
}
|
|
177
|
+
trimInstallerStateRoot(installerState);
|
|
178
|
+
return installerState;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function removeManagedPluginToolExposure(existingTools = {}) {
|
|
182
|
+
const tools = ensureObject(existingTools);
|
|
183
|
+
const allow = asStringArray(tools.allow).filter((toolName) => toolName !== CLAWORLD_PLUGIN_TOOL_ALLOW_ENTRY);
|
|
184
|
+
const alsoAllow = asStringArray(tools.alsoAllow).filter((toolName) => toolName !== CLAWORLD_PLUGIN_TOOL_ALLOW_ENTRY);
|
|
185
|
+
const nextTools = { ...tools };
|
|
186
|
+
if (allow.length > 0) nextTools.allow = uniqueStrings(allow);
|
|
187
|
+
else delete nextTools.allow;
|
|
188
|
+
if (alsoAllow.length > 0) nextTools.alsoAllow = uniqueStrings(alsoAllow);
|
|
189
|
+
else delete nextTools.alsoAllow;
|
|
190
|
+
return Object.keys(nextTools).length > 0 ? nextTools : null;
|
|
191
|
+
}
|
|
192
|
+
|
|
133
193
|
const SESSION_VISIBILITY_RANK = Object.freeze({
|
|
134
194
|
self: 0,
|
|
135
195
|
tree: 1,
|
|
@@ -295,22 +355,21 @@ function buildManagedAccountEntry(options = {}) {
|
|
|
295
355
|
|
|
296
356
|
if (options.appToken) {
|
|
297
357
|
base.appToken = options.appToken;
|
|
298
|
-
} else {
|
|
358
|
+
} else if (normalizeText(options.registrationDisplayName, null)) {
|
|
299
359
|
base.registration = {
|
|
300
360
|
enabled: true,
|
|
301
|
-
|
|
302
|
-
displayName: options.displayName,
|
|
361
|
+
displayName: normalizeText(options.registrationDisplayName, options.displayName),
|
|
303
362
|
};
|
|
304
363
|
}
|
|
305
364
|
|
|
306
|
-
if (!options.
|
|
365
|
+
if (!options.defaultTargetAgentId) {
|
|
307
366
|
return base;
|
|
308
367
|
}
|
|
309
368
|
|
|
310
369
|
return {
|
|
311
370
|
...base,
|
|
312
371
|
relay: {
|
|
313
|
-
|
|
372
|
+
defaultTargetAgentId: options.defaultTargetAgentId,
|
|
314
373
|
},
|
|
315
374
|
};
|
|
316
375
|
}
|
|
@@ -331,11 +390,11 @@ function buildMergedAccountEntry(existingAccount = {}, options = {}) {
|
|
|
331
390
|
...existingApproval,
|
|
332
391
|
mode: normalizeChatRequestApprovalMode(options.approvalMode, DEFAULT_CLAWORLD_APPROVAL_MODE),
|
|
333
392
|
},
|
|
334
|
-
...(options.
|
|
393
|
+
...(options.defaultTargetAgentId
|
|
335
394
|
? {
|
|
336
395
|
relay: {
|
|
337
396
|
...existingRelay,
|
|
338
|
-
|
|
397
|
+
defaultTargetAgentId: options.defaultTargetAgentId,
|
|
339
398
|
},
|
|
340
399
|
}
|
|
341
400
|
: existingAccount.relay
|
|
@@ -345,10 +404,18 @@ function buildMergedAccountEntry(existingAccount = {}, options = {}) {
|
|
|
345
404
|
delete merged.toolProfile;
|
|
346
405
|
|
|
347
406
|
if (options.appToken) {
|
|
348
|
-
|
|
407
|
+
const withToken = {
|
|
349
408
|
...merged,
|
|
350
409
|
appToken: options.appToken,
|
|
351
410
|
};
|
|
411
|
+
delete withToken.registration;
|
|
412
|
+
return withToken;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (!normalizeText(options.registrationDisplayName, null)) {
|
|
416
|
+
const withoutRegistration = { ...merged };
|
|
417
|
+
delete withoutRegistration.registration;
|
|
418
|
+
return withoutRegistration;
|
|
352
419
|
}
|
|
353
420
|
|
|
354
421
|
return {
|
|
@@ -356,19 +423,11 @@ function buildMergedAccountEntry(existingAccount = {}, options = {}) {
|
|
|
356
423
|
registration: {
|
|
357
424
|
...existingRegistration,
|
|
358
425
|
enabled: true,
|
|
359
|
-
|
|
360
|
-
displayName: options.displayName,
|
|
426
|
+
displayName: normalizeText(options.registrationDisplayName, options.displayName),
|
|
361
427
|
},
|
|
362
428
|
};
|
|
363
429
|
}
|
|
364
430
|
|
|
365
|
-
export function canonicalRelayAgentCode(registrationAgentCode, defaultToAddress = null) {
|
|
366
|
-
const normalizedAgentCode = normalizeRegistrationAgentCode(registrationAgentCode, null);
|
|
367
|
-
if (!normalizedAgentCode) return null;
|
|
368
|
-
if (normalizedAgentCode.includes('@')) return normalizedAgentCode;
|
|
369
|
-
return `${normalizedAgentCode}@${inferRelayDomain(defaultToAddress)}`;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
431
|
export function normalizeClaworldToolProfile(toolProfile = DEFAULT_CLAWORLD_TOOL_PROFILE) {
|
|
373
432
|
const normalized = normalizeText(toolProfile, DEFAULT_CLAWORLD_TOOL_PROFILE);
|
|
374
433
|
if (normalized === 'world') return 'default';
|
|
@@ -455,16 +514,15 @@ function describeToolAllowEntries(toolNames = []) {
|
|
|
455
514
|
export function buildWorkspaceAgentsContent({
|
|
456
515
|
agentId,
|
|
457
516
|
accountId,
|
|
458
|
-
|
|
517
|
+
registrationDisplayName,
|
|
459
518
|
appToken = null,
|
|
460
|
-
|
|
519
|
+
defaultTargetAgentId = null,
|
|
461
520
|
} = {}) {
|
|
462
|
-
const
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
: '- relay identity is resolved during runtime bootstrap';
|
|
521
|
+
const identityLine = appToken
|
|
522
|
+
? '- relay binding is resolved from the configured appToken at runtime'
|
|
523
|
+
: registrationDisplayName
|
|
524
|
+
? '- relay binding is created during runtime bootstrap and persists as backend-issued credentials'
|
|
525
|
+
: '- activation is pending until the user completes Claworld public identity setup';
|
|
468
526
|
|
|
469
527
|
return `# Claworld Channel Agent
|
|
470
528
|
|
|
@@ -474,8 +532,9 @@ Routing contract:
|
|
|
474
532
|
|
|
475
533
|
- local OpenClaw agent id: \`${agentId}\`
|
|
476
534
|
- claworld account id: \`${accountId}\`
|
|
477
|
-
${
|
|
535
|
+
${registrationDisplayName ? `- bootstrap display name: \`${registrationDisplayName}\`` : (appToken ? '- credential mode: appToken/manual binding' : '- credential mode: activation pending')}
|
|
478
536
|
${identityLine}
|
|
537
|
+
${defaultTargetAgentId ? `- default outbound target agentId: \`${defaultTargetAgentId}\`` : '- outbound sends require explicit target agentId inputs'}
|
|
479
538
|
|
|
480
539
|
Operating rules:
|
|
481
540
|
|
|
@@ -498,22 +557,23 @@ function buildBoundAgentEntry(existingAgent = {}, agentId) {
|
|
|
498
557
|
export function buildWorkspaceMemoryContent({
|
|
499
558
|
agentId,
|
|
500
559
|
accountId,
|
|
501
|
-
|
|
560
|
+
registrationDisplayName,
|
|
502
561
|
appToken = null,
|
|
503
|
-
|
|
562
|
+
defaultTargetAgentId = null,
|
|
504
563
|
} = {}) {
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
: '- relay identity: assigned during runtime bootstrap';
|
|
564
|
+
const identityLine = appToken
|
|
565
|
+
? '- relay binding: resolved from appToken at runtime'
|
|
566
|
+
: registrationDisplayName
|
|
567
|
+
? '- relay binding: assigned during runtime bootstrap'
|
|
568
|
+
: '- relay binding: pending until public identity setup completes';
|
|
511
569
|
|
|
512
570
|
return `# Claworld Memory
|
|
513
571
|
|
|
514
572
|
- workspace owner: \`${agentId}\`
|
|
515
573
|
- claworld account: \`${accountId}\`
|
|
574
|
+
${registrationDisplayName ? `- bootstrap display name: \`${registrationDisplayName}\`` : ''}
|
|
516
575
|
${identityLine}
|
|
576
|
+
${defaultTargetAgentId ? `- default outbound target agentId: \`${defaultTargetAgentId}\`` : ''}
|
|
517
577
|
|
|
518
578
|
Use this file for durable Claworld-specific notes only.
|
|
519
579
|
|
|
@@ -527,10 +587,6 @@ export function resolveDefaultManagedWorkspace(agentId = DEFAULT_CLAWORLD_AGENT_
|
|
|
527
587
|
return `~/.openclaw/workspace-${agentId}`;
|
|
528
588
|
}
|
|
529
589
|
|
|
530
|
-
export function resolveDefaultManagedRegistrationAgentCode(accountId = DEFAULT_CLAWORLD_ACCOUNT_ID) {
|
|
531
|
-
return null;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
590
|
export function resolveDefaultManagedDisplayName(accountId = DEFAULT_CLAWORLD_ACCOUNT_ID) {
|
|
535
591
|
return `${titleCase(accountId)} Channel Agent`;
|
|
536
592
|
}
|
|
@@ -551,10 +607,13 @@ export function resolveClaworldManagedRuntimeOptions({
|
|
|
551
607
|
accountId = null,
|
|
552
608
|
input = {},
|
|
553
609
|
overrides = {},
|
|
610
|
+
installerState = null,
|
|
554
611
|
} = {}) {
|
|
555
612
|
const resolvedAccountId = normalizeText(accountId, DEFAULT_CLAWORLD_ACCOUNT_ID);
|
|
556
613
|
const attachToExistingAgent = overrides.attachToExistingAgent !== false;
|
|
557
|
-
const
|
|
614
|
+
const existingBackup = findClaworldManagedRuntimeBackup(installerState, resolvedAccountId);
|
|
615
|
+
const inferredAgentId = inferExistingAgentId(cfg, resolvedAccountId)
|
|
616
|
+
|| normalizeText(existingBackup.agentId, null);
|
|
558
617
|
const agentId = normalizeText(overrides.agentId, inferredAgentId);
|
|
559
618
|
const existingAgent = findAgentEntry(cfg, agentId);
|
|
560
619
|
const existingAccount = findManagedAccountEntry(cfg, resolvedAccountId);
|
|
@@ -570,23 +629,23 @@ export function resolveClaworldManagedRuntimeOptions({
|
|
|
570
629
|
const workspace = normalizeText(
|
|
571
630
|
explicitWorkspace,
|
|
572
631
|
replaceManagedRuntime
|
|
573
|
-
? normalizeText(existingAgent?.workspace, defaultWorkspace)
|
|
574
|
-
: normalizeText(existingAgent?.workspace, defaultWorkspace),
|
|
632
|
+
? normalizeText(existingAgent?.workspace, normalizeText(existingBackup.workspace, defaultWorkspace))
|
|
633
|
+
: normalizeText(existingAgent?.workspace, normalizeText(existingBackup.workspace, defaultWorkspace)),
|
|
575
634
|
);
|
|
576
635
|
const serverUrl = normalizeText(
|
|
577
636
|
overrides.serverUrl,
|
|
578
|
-
normalizeText(input.httpUrl, normalizeText(input.url, DEFAULT_CLAWORLD_SERVER_URL)),
|
|
637
|
+
normalizeText(input.httpUrl, normalizeText(input.url, normalizeText(existingBackup.serverUrl, DEFAULT_CLAWORLD_SERVER_URL))),
|
|
579
638
|
);
|
|
580
|
-
const apiKey = normalizeText(overrides.apiKey, DEFAULT_CLAWORLD_API_KEY);
|
|
639
|
+
const apiKey = normalizeText(overrides.apiKey, normalizeText(existingBackup.apiKey, DEFAULT_CLAWORLD_API_KEY));
|
|
581
640
|
const explicitAppToken = normalizeText(
|
|
582
641
|
overrides.appToken,
|
|
583
642
|
normalizeText(input.appToken, null),
|
|
584
643
|
);
|
|
585
|
-
const
|
|
586
|
-
overrides.
|
|
587
|
-
|
|
644
|
+
const explicitRegistrationDisplayName = normalizeRegistrationDisplayName(
|
|
645
|
+
overrides.registrationDisplayName,
|
|
646
|
+
normalizeRegistrationDisplayName(input.name, null),
|
|
588
647
|
);
|
|
589
|
-
const appToken =
|
|
648
|
+
const appToken = explicitRegistrationDisplayName && !explicitAppToken
|
|
590
649
|
? null
|
|
591
650
|
: normalizeText(
|
|
592
651
|
explicitAppToken,
|
|
@@ -594,35 +653,36 @@ export function resolveClaworldManagedRuntimeOptions({
|
|
|
594
653
|
existingAccount.appToken,
|
|
595
654
|
normalizeText(
|
|
596
655
|
existingAccount?.relay?.appToken,
|
|
597
|
-
normalizeText(existingAccount?.relay?.credentialToken, null),
|
|
656
|
+
normalizeText(existingAccount?.relay?.credentialToken, normalizeText(existingBackup.appToken, null)),
|
|
598
657
|
),
|
|
599
658
|
),
|
|
600
659
|
);
|
|
601
660
|
const displayName = normalizeText(
|
|
602
661
|
overrides.displayName,
|
|
603
|
-
normalizeText(input.name, resolveDefaultManagedDisplayName(resolvedAccountId)),
|
|
662
|
+
normalizeText(input.name, normalizeText(existingBackup.displayName, resolveDefaultManagedDisplayName(resolvedAccountId))),
|
|
604
663
|
);
|
|
605
|
-
const name = normalizeText(overrides.name, displayName);
|
|
606
|
-
const
|
|
607
|
-
existingAccount?.registration?.
|
|
608
|
-
|
|
664
|
+
const name = normalizeText(overrides.name, normalizeText(existingBackup.name, displayName));
|
|
665
|
+
const existingRegistrationDisplayName = normalizeRegistrationDisplayName(
|
|
666
|
+
existingAccount?.registration?.displayName,
|
|
667
|
+
normalizeRegistrationDisplayName(
|
|
668
|
+
existingAccount?.localAgent?.displayName,
|
|
669
|
+
normalizeRegistrationDisplayName(existingBackup.registrationDisplayName, null),
|
|
670
|
+
),
|
|
609
671
|
);
|
|
610
|
-
const
|
|
672
|
+
const registrationDisplayName = appToken && !explicitRegistrationDisplayName
|
|
611
673
|
? null
|
|
612
|
-
:
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
normalizeRegistrationAgentCode(
|
|
616
|
-
resolveDefaultManagedRegistrationAgentCode(resolvedAccountId),
|
|
617
|
-
existingRegistrationAgentCode,
|
|
618
|
-
),
|
|
619
|
-
),
|
|
674
|
+
: normalizeRegistrationDisplayName(
|
|
675
|
+
explicitRegistrationDisplayName,
|
|
676
|
+
existingRegistrationDisplayName,
|
|
620
677
|
);
|
|
621
678
|
const approvalMode = normalizeChatRequestApprovalMode(
|
|
622
679
|
normalizeText(overrides.approvalMode, null),
|
|
623
680
|
typeof overrides.autoAccept === 'boolean'
|
|
624
681
|
? (overrides.autoAccept ? 'open' : DEFAULT_CLAWORLD_APPROVAL_MODE)
|
|
625
|
-
:
|
|
682
|
+
: normalizeChatRequestApprovalMode(
|
|
683
|
+
normalizeText(existingBackup.approvalMode, null),
|
|
684
|
+
resolveStoredApprovalMode(existingAccount),
|
|
685
|
+
),
|
|
626
686
|
);
|
|
627
687
|
|
|
628
688
|
return {
|
|
@@ -638,14 +698,14 @@ export function resolveClaworldManagedRuntimeOptions({
|
|
|
638
698
|
serverUrl,
|
|
639
699
|
apiKey,
|
|
640
700
|
appToken,
|
|
641
|
-
|
|
701
|
+
registrationDisplayName,
|
|
642
702
|
displayName,
|
|
643
703
|
name,
|
|
644
|
-
|
|
704
|
+
defaultTargetAgentId: normalizeText(overrides.defaultTargetAgentId, null),
|
|
645
705
|
approvalMode,
|
|
646
706
|
sessionDmScope: normalizeText(
|
|
647
707
|
overrides.sessionDmScope,
|
|
648
|
-
DEFAULT_CLAWORLD_DM_SCOPE,
|
|
708
|
+
normalizeText(existingBackup.sessionDmScope, DEFAULT_CLAWORLD_DM_SCOPE),
|
|
649
709
|
),
|
|
650
710
|
replaceManagedRuntime,
|
|
651
711
|
preserveDefaultAccount: overrides.preserveDefaultAccount === true,
|
|
@@ -665,10 +725,6 @@ export function applyClaworldManagedRuntimeConfig(inputConfig = {}, options = {}
|
|
|
665
725
|
const sessionDmScope = normalizeText(options.sessionDmScope, DEFAULT_CLAWORLD_DM_SCOPE);
|
|
666
726
|
const manageAgentEntry = options.manageAgentEntry === true;
|
|
667
727
|
|
|
668
|
-
if (!options.appToken && !normalizeText(options.registrationAgentCode, null)) {
|
|
669
|
-
throw new Error('claworld registration agentCode is required when appToken is absent');
|
|
670
|
-
}
|
|
671
|
-
|
|
672
728
|
const removedManagedToolNames = new Set([
|
|
673
729
|
...CLAWORLD_PUBLIC_TOOL_NAMES,
|
|
674
730
|
...CLAWORLD_COMPATIBILITY_TOOL_NAMES,
|
|
@@ -829,10 +885,164 @@ export function applyClaworldManagedRuntimeConfig(inputConfig = {}, options = {}
|
|
|
829
885
|
return {
|
|
830
886
|
config,
|
|
831
887
|
summary,
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
888
|
+
bootstrapDisplayName: normalizeText(options.registrationDisplayName, null),
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
export function stripClaworldManagedRuntimeConfig(inputConfig = {}, {
|
|
893
|
+
accountId = DEFAULT_CLAWORLD_ACCOUNT_ID,
|
|
894
|
+
agentId = null,
|
|
895
|
+
preserveBackup = true,
|
|
896
|
+
} = {}) {
|
|
897
|
+
const config = JSON.parse(JSON.stringify(ensureObject(inputConfig)));
|
|
898
|
+
const summary = [];
|
|
899
|
+
const resolvedAccountId = normalizeText(accountId, DEFAULT_CLAWORLD_ACCOUNT_ID);
|
|
900
|
+
const resolvedAgentId = normalizeText(agentId, inferExistingAgentId(config, resolvedAccountId));
|
|
901
|
+
const existingAgent = findAgentEntry(config, resolvedAgentId);
|
|
902
|
+
const existingAccount = findManagedAccountEntry(config, resolvedAccountId);
|
|
903
|
+
const existingToolProfile = resolveStoredClaworldToolProfile(existingAccount) || inferClaworldToolProfile(config);
|
|
904
|
+
const backup = preserveBackup
|
|
905
|
+
? {
|
|
906
|
+
version: CLAWORLD_MANAGED_RUNTIME_BACKUP_VERSION,
|
|
907
|
+
accountId: resolvedAccountId,
|
|
908
|
+
agentId: resolvedAgentId,
|
|
909
|
+
workspace: normalizeText(existingAgent?.workspace, null),
|
|
910
|
+
serverUrl: normalizeText(existingAccount.serverUrl, null),
|
|
911
|
+
apiKey: normalizeText(existingAccount.apiKey, null),
|
|
912
|
+
appToken: normalizeText(
|
|
913
|
+
existingAccount.appToken,
|
|
914
|
+
normalizeText(existingAccount?.relay?.appToken, normalizeText(existingAccount?.relay?.credentialToken, null)),
|
|
915
|
+
),
|
|
916
|
+
displayName: normalizeText(existingAccount.name, normalizeText(existingAgent?.name, null)),
|
|
917
|
+
name: normalizeText(existingAccount.name, null),
|
|
918
|
+
registrationDisplayName: normalizeRegistrationDisplayName(existingAccount?.registration?.displayName, null),
|
|
919
|
+
approvalMode: normalizeChatRequestApprovalMode(existingAccount?.approval?.mode, DEFAULT_CLAWORLD_APPROVAL_MODE),
|
|
920
|
+
sessionDmScope: normalizeText(config?.session?.dmScope, DEFAULT_CLAWORLD_DM_SCOPE),
|
|
921
|
+
toolProfile: existingToolProfile,
|
|
922
|
+
preservedAt: new Date().toISOString(),
|
|
923
|
+
}
|
|
924
|
+
: null;
|
|
925
|
+
if (backup) {
|
|
926
|
+
summary.push(`prepared managed claworld runtime backup for ${resolvedAccountId}`);
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
if (resolvedAgentId) {
|
|
930
|
+
const agentList = Array.isArray(config?.agents?.list) ? [...config.agents.list] : [];
|
|
931
|
+
const agentIndex = findAgentIndex(agentList, resolvedAgentId);
|
|
932
|
+
if (agentIndex >= 0) {
|
|
933
|
+
const nextAgent = { ...ensureObject(agentList[agentIndex]) };
|
|
934
|
+
const nextTools = removeManagedPluginToolExposure(nextAgent.tools);
|
|
935
|
+
if (nextTools) nextAgent.tools = nextTools;
|
|
936
|
+
else delete nextAgent.tools;
|
|
937
|
+
agentList[agentIndex] = nextAgent;
|
|
938
|
+
config.agents = ensureObject(config.agents);
|
|
939
|
+
config.agents.list = agentList;
|
|
940
|
+
summary.push(`removed managed claworld tool exposure from agent ${resolvedAgentId}`);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
const claworldRoot = ensureObject(config?.channels?.claworld);
|
|
945
|
+
const accounts = ensureObject(claworldRoot.accounts);
|
|
946
|
+
if (Object.prototype.hasOwnProperty.call(accounts, resolvedAccountId)) {
|
|
947
|
+
delete accounts[resolvedAccountId];
|
|
948
|
+
summary.push(`removed channels.claworld.accounts.${resolvedAccountId}`);
|
|
949
|
+
}
|
|
950
|
+
const nextClaworldRoot = { ...claworldRoot };
|
|
951
|
+
if (Object.keys(accounts).length > 0) {
|
|
952
|
+
nextClaworldRoot.accounts = accounts;
|
|
953
|
+
const currentDefaultAccount = normalizeText(nextClaworldRoot.defaultAccount, null);
|
|
954
|
+
if (currentDefaultAccount === resolvedAccountId) {
|
|
955
|
+
nextClaworldRoot.defaultAccount = Object.keys(accounts)[0];
|
|
956
|
+
summary.push(`repointed channels.claworld.defaultAccount to ${nextClaworldRoot.defaultAccount}`);
|
|
957
|
+
}
|
|
958
|
+
} else {
|
|
959
|
+
delete nextClaworldRoot.accounts;
|
|
960
|
+
delete nextClaworldRoot.defaultAccount;
|
|
961
|
+
}
|
|
962
|
+
if (Object.keys(nextClaworldRoot).length > 0) {
|
|
963
|
+
config.channels = ensureObject(config.channels);
|
|
964
|
+
config.channels.claworld = nextClaworldRoot;
|
|
965
|
+
} else if (config.channels && typeof config.channels === 'object' && !Array.isArray(config.channels)) {
|
|
966
|
+
delete config.channels.claworld;
|
|
967
|
+
if (Object.keys(config.channels).length === 0) {
|
|
968
|
+
delete config.channels;
|
|
969
|
+
}
|
|
970
|
+
summary.push('removed channels.claworld root');
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
if (Array.isArray(config.bindings)) {
|
|
974
|
+
const nextBindings = config.bindings.filter((binding) => {
|
|
975
|
+
const candidate = ensureObject(binding);
|
|
976
|
+
const match = ensureObject(candidate.match);
|
|
977
|
+
const bindingChannel = normalizeText(match.channel, null);
|
|
978
|
+
const bindingAccountId = normalizeText(match.accountId, null);
|
|
979
|
+
const bindingAgentId = normalizeText(candidate.agentId, null);
|
|
980
|
+
if (bindingChannel !== 'claworld') return true;
|
|
981
|
+
if (bindingAccountId === resolvedAccountId) return false;
|
|
982
|
+
if (!bindingAccountId && resolvedAgentId && bindingAgentId === resolvedAgentId) return false;
|
|
983
|
+
return true;
|
|
984
|
+
});
|
|
985
|
+
if (nextBindings.length !== config.bindings.length) {
|
|
986
|
+
config.bindings = nextBindings;
|
|
987
|
+
summary.push(`removed claworld bindings for ${resolvedAccountId}`);
|
|
988
|
+
}
|
|
989
|
+
if (config.bindings.length === 0) {
|
|
990
|
+
delete config.bindings;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
config.plugins = ensureObject(config.plugins);
|
|
995
|
+
const nextPluginAllow = asStringArray(config.plugins.allow).filter((pluginId) => pluginId !== 'claworld');
|
|
996
|
+
if (nextPluginAllow.length > 0) config.plugins.allow = uniqueStrings(nextPluginAllow);
|
|
997
|
+
else delete config.plugins.allow;
|
|
998
|
+
|
|
999
|
+
const nextPluginEntries = ensureObject(config.plugins.entries);
|
|
1000
|
+
if (Object.prototype.hasOwnProperty.call(nextPluginEntries, 'claworld')) {
|
|
1001
|
+
delete nextPluginEntries.claworld;
|
|
1002
|
+
summary.push('removed plugins.entries.claworld');
|
|
1003
|
+
}
|
|
1004
|
+
if (Object.keys(nextPluginEntries).length > 0) config.plugins.entries = nextPluginEntries;
|
|
1005
|
+
else delete config.plugins.entries;
|
|
1006
|
+
|
|
1007
|
+
const nextPluginInstalls = ensureObject(config.plugins.installs);
|
|
1008
|
+
const claworldInstallRecord = ensureObject(nextPluginInstalls.claworld);
|
|
1009
|
+
if (Object.prototype.hasOwnProperty.call(nextPluginInstalls, 'claworld')) {
|
|
1010
|
+
delete nextPluginInstalls.claworld;
|
|
1011
|
+
summary.push('removed plugins.installs.claworld');
|
|
1012
|
+
}
|
|
1013
|
+
if (Object.keys(nextPluginInstalls).length > 0) config.plugins.installs = nextPluginInstalls;
|
|
1014
|
+
else delete config.plugins.installs;
|
|
1015
|
+
|
|
1016
|
+
const nextPluginLoad = ensureObject(config.plugins.load);
|
|
1017
|
+
const sourcePath = normalizeText(claworldInstallRecord.sourcePath, null);
|
|
1018
|
+
const filteredLoadPaths = asStringArray(nextPluginLoad.paths).filter((entry) => entry !== sourcePath);
|
|
1019
|
+
if (sourcePath && filteredLoadPaths.length !== asStringArray(nextPluginLoad.paths).length) {
|
|
1020
|
+
if (filteredLoadPaths.length > 0) {
|
|
1021
|
+
nextPluginLoad.paths = uniqueStrings(filteredLoadPaths);
|
|
1022
|
+
} else {
|
|
1023
|
+
delete nextPluginLoad.paths;
|
|
1024
|
+
}
|
|
1025
|
+
summary.push('removed plugins.load.paths claworld sourcePath');
|
|
1026
|
+
}
|
|
1027
|
+
if (Object.keys(nextPluginLoad).length > 0) config.plugins.load = nextPluginLoad;
|
|
1028
|
+
else delete config.plugins.load;
|
|
1029
|
+
|
|
1030
|
+
const nextPluginSlots = ensureObject(config.plugins.slots);
|
|
1031
|
+
if (normalizeText(nextPluginSlots.memory, null) === 'claworld') {
|
|
1032
|
+
delete nextPluginSlots.memory;
|
|
1033
|
+
summary.push('removed plugins.slots.memory claworld');
|
|
1034
|
+
}
|
|
1035
|
+
if (Object.keys(nextPluginSlots).length > 0) config.plugins.slots = nextPluginSlots;
|
|
1036
|
+
else delete config.plugins.slots;
|
|
1037
|
+
|
|
1038
|
+
if (Object.keys(config.plugins).length === 0) {
|
|
1039
|
+
delete config.plugins;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
return {
|
|
1043
|
+
config,
|
|
1044
|
+
summary,
|
|
1045
|
+
backup,
|
|
836
1046
|
};
|
|
837
1047
|
}
|
|
838
1048
|
|