@xfxstudio/claworld 0.2.9 → 0.2.10-beta.0
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 +46 -1
- package/src/openclaw/installer/constants.js +1 -0
- package/src/openclaw/installer/core.js +234 -3
- package/src/openclaw/installer/doctor.js +2 -2
- package/src/openclaw/plugin/account-identity.js +1 -2
- package/src/openclaw/plugin/claworld-channel-plugin.js +270 -255
- package/src/openclaw/plugin/config-schema.js +9 -23
- package/src/openclaw/plugin/managed-config.js +284 -79
- package/src/openclaw/plugin/onboarding.js +22 -42
- package/src/openclaw/plugin/register.js +109 -10
- 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 +10 -21
- 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,
|
|
@@ -298,19 +358,18 @@ function buildManagedAccountEntry(options = {}) {
|
|
|
298
358
|
} else {
|
|
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
|
|
@@ -356,19 +415,11 @@ function buildMergedAccountEntry(existingAccount = {}, options = {}) {
|
|
|
356
415
|
registration: {
|
|
357
416
|
...existingRegistration,
|
|
358
417
|
enabled: true,
|
|
359
|
-
|
|
360
|
-
displayName: options.displayName,
|
|
418
|
+
displayName: normalizeText(options.registrationDisplayName, options.displayName),
|
|
361
419
|
},
|
|
362
420
|
};
|
|
363
421
|
}
|
|
364
422
|
|
|
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
423
|
export function normalizeClaworldToolProfile(toolProfile = DEFAULT_CLAWORLD_TOOL_PROFILE) {
|
|
373
424
|
const normalized = normalizeText(toolProfile, DEFAULT_CLAWORLD_TOOL_PROFILE);
|
|
374
425
|
if (normalized === 'world') return 'default';
|
|
@@ -455,16 +506,13 @@ function describeToolAllowEntries(toolNames = []) {
|
|
|
455
506
|
export function buildWorkspaceAgentsContent({
|
|
456
507
|
agentId,
|
|
457
508
|
accountId,
|
|
458
|
-
|
|
509
|
+
registrationDisplayName,
|
|
459
510
|
appToken = null,
|
|
460
|
-
|
|
511
|
+
defaultTargetAgentId = null,
|
|
461
512
|
} = {}) {
|
|
462
|
-
const
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
: appToken
|
|
466
|
-
? '- relay identity is resolved from the configured appToken at runtime'
|
|
467
|
-
: '- relay identity is resolved during runtime bootstrap';
|
|
513
|
+
const identityLine = appToken
|
|
514
|
+
? '- relay binding is resolved from the configured appToken at runtime'
|
|
515
|
+
: '- relay binding is created during runtime bootstrap and persists as backend-issued credentials';
|
|
468
516
|
|
|
469
517
|
return `# Claworld Channel Agent
|
|
470
518
|
|
|
@@ -474,8 +522,9 @@ Routing contract:
|
|
|
474
522
|
|
|
475
523
|
- local OpenClaw agent id: \`${agentId}\`
|
|
476
524
|
- claworld account id: \`${accountId}\`
|
|
477
|
-
${
|
|
525
|
+
${registrationDisplayName ? `- bootstrap display name: \`${registrationDisplayName}\`` : '- credential mode: appToken/manual binding'}
|
|
478
526
|
${identityLine}
|
|
527
|
+
${defaultTargetAgentId ? `- default outbound target agentId: \`${defaultTargetAgentId}\`` : '- outbound sends require explicit target agentId inputs'}
|
|
479
528
|
|
|
480
529
|
Operating rules:
|
|
481
530
|
|
|
@@ -498,22 +547,21 @@ function buildBoundAgentEntry(existingAgent = {}, agentId) {
|
|
|
498
547
|
export function buildWorkspaceMemoryContent({
|
|
499
548
|
agentId,
|
|
500
549
|
accountId,
|
|
501
|
-
|
|
550
|
+
registrationDisplayName,
|
|
502
551
|
appToken = null,
|
|
503
|
-
|
|
552
|
+
defaultTargetAgentId = null,
|
|
504
553
|
} = {}) {
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
: appToken
|
|
509
|
-
? '- relay identity: resolved from appToken at runtime'
|
|
510
|
-
: '- relay identity: assigned during runtime bootstrap';
|
|
554
|
+
const identityLine = appToken
|
|
555
|
+
? '- relay binding: resolved from appToken at runtime'
|
|
556
|
+
: '- relay binding: assigned during runtime bootstrap';
|
|
511
557
|
|
|
512
558
|
return `# Claworld Memory
|
|
513
559
|
|
|
514
560
|
- workspace owner: \`${agentId}\`
|
|
515
561
|
- claworld account: \`${accountId}\`
|
|
562
|
+
${registrationDisplayName ? `- bootstrap display name: \`${registrationDisplayName}\`` : ''}
|
|
516
563
|
${identityLine}
|
|
564
|
+
${defaultTargetAgentId ? `- default outbound target agentId: \`${defaultTargetAgentId}\`` : ''}
|
|
517
565
|
|
|
518
566
|
Use this file for durable Claworld-specific notes only.
|
|
519
567
|
|
|
@@ -527,10 +575,6 @@ export function resolveDefaultManagedWorkspace(agentId = DEFAULT_CLAWORLD_AGENT_
|
|
|
527
575
|
return `~/.openclaw/workspace-${agentId}`;
|
|
528
576
|
}
|
|
529
577
|
|
|
530
|
-
export function resolveDefaultManagedRegistrationAgentCode(accountId = DEFAULT_CLAWORLD_ACCOUNT_ID) {
|
|
531
|
-
return null;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
578
|
export function resolveDefaultManagedDisplayName(accountId = DEFAULT_CLAWORLD_ACCOUNT_ID) {
|
|
535
579
|
return `${titleCase(accountId)} Channel Agent`;
|
|
536
580
|
}
|
|
@@ -551,10 +595,13 @@ export function resolveClaworldManagedRuntimeOptions({
|
|
|
551
595
|
accountId = null,
|
|
552
596
|
input = {},
|
|
553
597
|
overrides = {},
|
|
598
|
+
installerState = null,
|
|
554
599
|
} = {}) {
|
|
555
600
|
const resolvedAccountId = normalizeText(accountId, DEFAULT_CLAWORLD_ACCOUNT_ID);
|
|
556
601
|
const attachToExistingAgent = overrides.attachToExistingAgent !== false;
|
|
557
|
-
const
|
|
602
|
+
const existingBackup = findClaworldManagedRuntimeBackup(installerState, resolvedAccountId);
|
|
603
|
+
const inferredAgentId = inferExistingAgentId(cfg, resolvedAccountId)
|
|
604
|
+
|| normalizeText(existingBackup.agentId, null);
|
|
558
605
|
const agentId = normalizeText(overrides.agentId, inferredAgentId);
|
|
559
606
|
const existingAgent = findAgentEntry(cfg, agentId);
|
|
560
607
|
const existingAccount = findManagedAccountEntry(cfg, resolvedAccountId);
|
|
@@ -570,23 +617,23 @@ export function resolveClaworldManagedRuntimeOptions({
|
|
|
570
617
|
const workspace = normalizeText(
|
|
571
618
|
explicitWorkspace,
|
|
572
619
|
replaceManagedRuntime
|
|
573
|
-
? normalizeText(existingAgent?.workspace, defaultWorkspace)
|
|
574
|
-
: normalizeText(existingAgent?.workspace, defaultWorkspace),
|
|
620
|
+
? normalizeText(existingAgent?.workspace, normalizeText(existingBackup.workspace, defaultWorkspace))
|
|
621
|
+
: normalizeText(existingAgent?.workspace, normalizeText(existingBackup.workspace, defaultWorkspace)),
|
|
575
622
|
);
|
|
576
623
|
const serverUrl = normalizeText(
|
|
577
624
|
overrides.serverUrl,
|
|
578
|
-
normalizeText(input.httpUrl, normalizeText(input.url, DEFAULT_CLAWORLD_SERVER_URL)),
|
|
625
|
+
normalizeText(input.httpUrl, normalizeText(input.url, normalizeText(existingBackup.serverUrl, DEFAULT_CLAWORLD_SERVER_URL))),
|
|
579
626
|
);
|
|
580
|
-
const apiKey = normalizeText(overrides.apiKey, DEFAULT_CLAWORLD_API_KEY);
|
|
627
|
+
const apiKey = normalizeText(overrides.apiKey, normalizeText(existingBackup.apiKey, DEFAULT_CLAWORLD_API_KEY));
|
|
581
628
|
const explicitAppToken = normalizeText(
|
|
582
629
|
overrides.appToken,
|
|
583
630
|
normalizeText(input.appToken, null),
|
|
584
631
|
);
|
|
585
|
-
const
|
|
586
|
-
overrides.
|
|
587
|
-
|
|
632
|
+
const explicitRegistrationDisplayName = normalizeRegistrationDisplayName(
|
|
633
|
+
overrides.registrationDisplayName,
|
|
634
|
+
normalizeRegistrationDisplayName(input.name, null),
|
|
588
635
|
);
|
|
589
|
-
const appToken =
|
|
636
|
+
const appToken = explicitRegistrationDisplayName && !explicitAppToken
|
|
590
637
|
? null
|
|
591
638
|
: normalizeText(
|
|
592
639
|
explicitAppToken,
|
|
@@ -594,35 +641,39 @@ export function resolveClaworldManagedRuntimeOptions({
|
|
|
594
641
|
existingAccount.appToken,
|
|
595
642
|
normalizeText(
|
|
596
643
|
existingAccount?.relay?.appToken,
|
|
597
|
-
normalizeText(existingAccount?.relay?.credentialToken, null),
|
|
644
|
+
normalizeText(existingAccount?.relay?.credentialToken, normalizeText(existingBackup.appToken, null)),
|
|
598
645
|
),
|
|
599
646
|
),
|
|
600
647
|
);
|
|
601
648
|
const displayName = normalizeText(
|
|
602
649
|
overrides.displayName,
|
|
603
|
-
normalizeText(input.name, resolveDefaultManagedDisplayName(resolvedAccountId)),
|
|
650
|
+
normalizeText(input.name, normalizeText(existingBackup.displayName, resolveDefaultManagedDisplayName(resolvedAccountId))),
|
|
604
651
|
);
|
|
605
|
-
const name = normalizeText(overrides.name, displayName);
|
|
606
|
-
const
|
|
607
|
-
existingAccount?.registration?.
|
|
608
|
-
|
|
652
|
+
const name = normalizeText(overrides.name, normalizeText(existingBackup.name, displayName));
|
|
653
|
+
const existingRegistrationDisplayName = normalizeRegistrationDisplayName(
|
|
654
|
+
existingAccount?.registration?.displayName,
|
|
655
|
+
normalizeRegistrationDisplayName(
|
|
656
|
+
existingAccount?.localAgent?.displayName,
|
|
657
|
+
normalizeRegistrationDisplayName(existingBackup.registrationDisplayName, null),
|
|
658
|
+
),
|
|
609
659
|
);
|
|
610
|
-
const
|
|
660
|
+
const registrationDisplayName = appToken && !explicitRegistrationDisplayName
|
|
611
661
|
? null
|
|
612
|
-
:
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
existingRegistrationAgentCode,
|
|
618
|
-
),
|
|
662
|
+
: normalizeRegistrationDisplayName(
|
|
663
|
+
explicitRegistrationDisplayName,
|
|
664
|
+
normalizeRegistrationDisplayName(
|
|
665
|
+
existingRegistrationDisplayName,
|
|
666
|
+
displayName,
|
|
619
667
|
),
|
|
620
668
|
);
|
|
621
669
|
const approvalMode = normalizeChatRequestApprovalMode(
|
|
622
670
|
normalizeText(overrides.approvalMode, null),
|
|
623
671
|
typeof overrides.autoAccept === 'boolean'
|
|
624
672
|
? (overrides.autoAccept ? 'open' : DEFAULT_CLAWORLD_APPROVAL_MODE)
|
|
625
|
-
:
|
|
673
|
+
: normalizeChatRequestApprovalMode(
|
|
674
|
+
normalizeText(existingBackup.approvalMode, null),
|
|
675
|
+
resolveStoredApprovalMode(existingAccount),
|
|
676
|
+
),
|
|
626
677
|
);
|
|
627
678
|
|
|
628
679
|
return {
|
|
@@ -638,14 +689,14 @@ export function resolveClaworldManagedRuntimeOptions({
|
|
|
638
689
|
serverUrl,
|
|
639
690
|
apiKey,
|
|
640
691
|
appToken,
|
|
641
|
-
|
|
692
|
+
registrationDisplayName,
|
|
642
693
|
displayName,
|
|
643
694
|
name,
|
|
644
|
-
|
|
695
|
+
defaultTargetAgentId: normalizeText(overrides.defaultTargetAgentId, null),
|
|
645
696
|
approvalMode,
|
|
646
697
|
sessionDmScope: normalizeText(
|
|
647
698
|
overrides.sessionDmScope,
|
|
648
|
-
DEFAULT_CLAWORLD_DM_SCOPE,
|
|
699
|
+
normalizeText(existingBackup.sessionDmScope, DEFAULT_CLAWORLD_DM_SCOPE),
|
|
649
700
|
),
|
|
650
701
|
replaceManagedRuntime,
|
|
651
702
|
preserveDefaultAccount: overrides.preserveDefaultAccount === true,
|
|
@@ -665,8 +716,8 @@ export function applyClaworldManagedRuntimeConfig(inputConfig = {}, options = {}
|
|
|
665
716
|
const sessionDmScope = normalizeText(options.sessionDmScope, DEFAULT_CLAWORLD_DM_SCOPE);
|
|
666
717
|
const manageAgentEntry = options.manageAgentEntry === true;
|
|
667
718
|
|
|
668
|
-
if (!options.appToken && !normalizeText(options.
|
|
669
|
-
throw new Error('claworld registration
|
|
719
|
+
if (!options.appToken && !normalizeText(options.registrationDisplayName, null)) {
|
|
720
|
+
throw new Error('claworld registration displayName is required when appToken is absent');
|
|
670
721
|
}
|
|
671
722
|
|
|
672
723
|
const removedManagedToolNames = new Set([
|
|
@@ -829,10 +880,164 @@ export function applyClaworldManagedRuntimeConfig(inputConfig = {}, options = {}
|
|
|
829
880
|
return {
|
|
830
881
|
config,
|
|
831
882
|
summary,
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
883
|
+
bootstrapDisplayName: normalizeText(options.registrationDisplayName, null),
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
export function stripClaworldManagedRuntimeConfig(inputConfig = {}, {
|
|
888
|
+
accountId = DEFAULT_CLAWORLD_ACCOUNT_ID,
|
|
889
|
+
agentId = null,
|
|
890
|
+
preserveBackup = true,
|
|
891
|
+
} = {}) {
|
|
892
|
+
const config = JSON.parse(JSON.stringify(ensureObject(inputConfig)));
|
|
893
|
+
const summary = [];
|
|
894
|
+
const resolvedAccountId = normalizeText(accountId, DEFAULT_CLAWORLD_ACCOUNT_ID);
|
|
895
|
+
const resolvedAgentId = normalizeText(agentId, inferExistingAgentId(config, resolvedAccountId));
|
|
896
|
+
const existingAgent = findAgentEntry(config, resolvedAgentId);
|
|
897
|
+
const existingAccount = findManagedAccountEntry(config, resolvedAccountId);
|
|
898
|
+
const existingToolProfile = resolveStoredClaworldToolProfile(existingAccount) || inferClaworldToolProfile(config);
|
|
899
|
+
const backup = preserveBackup
|
|
900
|
+
? {
|
|
901
|
+
version: CLAWORLD_MANAGED_RUNTIME_BACKUP_VERSION,
|
|
902
|
+
accountId: resolvedAccountId,
|
|
903
|
+
agentId: resolvedAgentId,
|
|
904
|
+
workspace: normalizeText(existingAgent?.workspace, null),
|
|
905
|
+
serverUrl: normalizeText(existingAccount.serverUrl, null),
|
|
906
|
+
apiKey: normalizeText(existingAccount.apiKey, null),
|
|
907
|
+
appToken: normalizeText(
|
|
908
|
+
existingAccount.appToken,
|
|
909
|
+
normalizeText(existingAccount?.relay?.appToken, normalizeText(existingAccount?.relay?.credentialToken, null)),
|
|
910
|
+
),
|
|
911
|
+
displayName: normalizeText(existingAccount.name, normalizeText(existingAgent?.name, null)),
|
|
912
|
+
name: normalizeText(existingAccount.name, null),
|
|
913
|
+
registrationDisplayName: normalizeRegistrationDisplayName(existingAccount?.registration?.displayName, null),
|
|
914
|
+
approvalMode: normalizeChatRequestApprovalMode(existingAccount?.approval?.mode, DEFAULT_CLAWORLD_APPROVAL_MODE),
|
|
915
|
+
sessionDmScope: normalizeText(config?.session?.dmScope, DEFAULT_CLAWORLD_DM_SCOPE),
|
|
916
|
+
toolProfile: existingToolProfile,
|
|
917
|
+
preservedAt: new Date().toISOString(),
|
|
918
|
+
}
|
|
919
|
+
: null;
|
|
920
|
+
if (backup) {
|
|
921
|
+
summary.push(`prepared managed claworld runtime backup for ${resolvedAccountId}`);
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
if (resolvedAgentId) {
|
|
925
|
+
const agentList = Array.isArray(config?.agents?.list) ? [...config.agents.list] : [];
|
|
926
|
+
const agentIndex = findAgentIndex(agentList, resolvedAgentId);
|
|
927
|
+
if (agentIndex >= 0) {
|
|
928
|
+
const nextAgent = { ...ensureObject(agentList[agentIndex]) };
|
|
929
|
+
const nextTools = removeManagedPluginToolExposure(nextAgent.tools);
|
|
930
|
+
if (nextTools) nextAgent.tools = nextTools;
|
|
931
|
+
else delete nextAgent.tools;
|
|
932
|
+
agentList[agentIndex] = nextAgent;
|
|
933
|
+
config.agents = ensureObject(config.agents);
|
|
934
|
+
config.agents.list = agentList;
|
|
935
|
+
summary.push(`removed managed claworld tool exposure from agent ${resolvedAgentId}`);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
const claworldRoot = ensureObject(config?.channels?.claworld);
|
|
940
|
+
const accounts = ensureObject(claworldRoot.accounts);
|
|
941
|
+
if (Object.prototype.hasOwnProperty.call(accounts, resolvedAccountId)) {
|
|
942
|
+
delete accounts[resolvedAccountId];
|
|
943
|
+
summary.push(`removed channels.claworld.accounts.${resolvedAccountId}`);
|
|
944
|
+
}
|
|
945
|
+
const nextClaworldRoot = { ...claworldRoot };
|
|
946
|
+
if (Object.keys(accounts).length > 0) {
|
|
947
|
+
nextClaworldRoot.accounts = accounts;
|
|
948
|
+
const currentDefaultAccount = normalizeText(nextClaworldRoot.defaultAccount, null);
|
|
949
|
+
if (currentDefaultAccount === resolvedAccountId) {
|
|
950
|
+
nextClaworldRoot.defaultAccount = Object.keys(accounts)[0];
|
|
951
|
+
summary.push(`repointed channels.claworld.defaultAccount to ${nextClaworldRoot.defaultAccount}`);
|
|
952
|
+
}
|
|
953
|
+
} else {
|
|
954
|
+
delete nextClaworldRoot.accounts;
|
|
955
|
+
delete nextClaworldRoot.defaultAccount;
|
|
956
|
+
}
|
|
957
|
+
if (Object.keys(nextClaworldRoot).length > 0) {
|
|
958
|
+
config.channels = ensureObject(config.channels);
|
|
959
|
+
config.channels.claworld = nextClaworldRoot;
|
|
960
|
+
} else if (config.channels && typeof config.channels === 'object' && !Array.isArray(config.channels)) {
|
|
961
|
+
delete config.channels.claworld;
|
|
962
|
+
if (Object.keys(config.channels).length === 0) {
|
|
963
|
+
delete config.channels;
|
|
964
|
+
}
|
|
965
|
+
summary.push('removed channels.claworld root');
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
if (Array.isArray(config.bindings)) {
|
|
969
|
+
const nextBindings = config.bindings.filter((binding) => {
|
|
970
|
+
const candidate = ensureObject(binding);
|
|
971
|
+
const match = ensureObject(candidate.match);
|
|
972
|
+
const bindingChannel = normalizeText(match.channel, null);
|
|
973
|
+
const bindingAccountId = normalizeText(match.accountId, null);
|
|
974
|
+
const bindingAgentId = normalizeText(candidate.agentId, null);
|
|
975
|
+
if (bindingChannel !== 'claworld') return true;
|
|
976
|
+
if (bindingAccountId === resolvedAccountId) return false;
|
|
977
|
+
if (!bindingAccountId && resolvedAgentId && bindingAgentId === resolvedAgentId) return false;
|
|
978
|
+
return true;
|
|
979
|
+
});
|
|
980
|
+
if (nextBindings.length !== config.bindings.length) {
|
|
981
|
+
config.bindings = nextBindings;
|
|
982
|
+
summary.push(`removed claworld bindings for ${resolvedAccountId}`);
|
|
983
|
+
}
|
|
984
|
+
if (config.bindings.length === 0) {
|
|
985
|
+
delete config.bindings;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
config.plugins = ensureObject(config.plugins);
|
|
990
|
+
const nextPluginAllow = asStringArray(config.plugins.allow).filter((pluginId) => pluginId !== 'claworld');
|
|
991
|
+
if (nextPluginAllow.length > 0) config.plugins.allow = uniqueStrings(nextPluginAllow);
|
|
992
|
+
else delete config.plugins.allow;
|
|
993
|
+
|
|
994
|
+
const nextPluginEntries = ensureObject(config.plugins.entries);
|
|
995
|
+
if (Object.prototype.hasOwnProperty.call(nextPluginEntries, 'claworld')) {
|
|
996
|
+
delete nextPluginEntries.claworld;
|
|
997
|
+
summary.push('removed plugins.entries.claworld');
|
|
998
|
+
}
|
|
999
|
+
if (Object.keys(nextPluginEntries).length > 0) config.plugins.entries = nextPluginEntries;
|
|
1000
|
+
else delete config.plugins.entries;
|
|
1001
|
+
|
|
1002
|
+
const nextPluginInstalls = ensureObject(config.plugins.installs);
|
|
1003
|
+
const claworldInstallRecord = ensureObject(nextPluginInstalls.claworld);
|
|
1004
|
+
if (Object.prototype.hasOwnProperty.call(nextPluginInstalls, 'claworld')) {
|
|
1005
|
+
delete nextPluginInstalls.claworld;
|
|
1006
|
+
summary.push('removed plugins.installs.claworld');
|
|
1007
|
+
}
|
|
1008
|
+
if (Object.keys(nextPluginInstalls).length > 0) config.plugins.installs = nextPluginInstalls;
|
|
1009
|
+
else delete config.plugins.installs;
|
|
1010
|
+
|
|
1011
|
+
const nextPluginLoad = ensureObject(config.plugins.load);
|
|
1012
|
+
const sourcePath = normalizeText(claworldInstallRecord.sourcePath, null);
|
|
1013
|
+
const filteredLoadPaths = asStringArray(nextPluginLoad.paths).filter((entry) => entry !== sourcePath);
|
|
1014
|
+
if (sourcePath && filteredLoadPaths.length !== asStringArray(nextPluginLoad.paths).length) {
|
|
1015
|
+
if (filteredLoadPaths.length > 0) {
|
|
1016
|
+
nextPluginLoad.paths = uniqueStrings(filteredLoadPaths);
|
|
1017
|
+
} else {
|
|
1018
|
+
delete nextPluginLoad.paths;
|
|
1019
|
+
}
|
|
1020
|
+
summary.push('removed plugins.load.paths claworld sourcePath');
|
|
1021
|
+
}
|
|
1022
|
+
if (Object.keys(nextPluginLoad).length > 0) config.plugins.load = nextPluginLoad;
|
|
1023
|
+
else delete config.plugins.load;
|
|
1024
|
+
|
|
1025
|
+
const nextPluginSlots = ensureObject(config.plugins.slots);
|
|
1026
|
+
if (normalizeText(nextPluginSlots.memory, null) === 'claworld') {
|
|
1027
|
+
delete nextPluginSlots.memory;
|
|
1028
|
+
summary.push('removed plugins.slots.memory claworld');
|
|
1029
|
+
}
|
|
1030
|
+
if (Object.keys(nextPluginSlots).length > 0) config.plugins.slots = nextPluginSlots;
|
|
1031
|
+
else delete config.plugins.slots;
|
|
1032
|
+
|
|
1033
|
+
if (Object.keys(config.plugins).length === 0) {
|
|
1034
|
+
delete config.plugins;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
return {
|
|
1038
|
+
config,
|
|
1039
|
+
summary,
|
|
1040
|
+
backup,
|
|
836
1041
|
};
|
|
837
1042
|
}
|
|
838
1043
|
|