@xfxstudio/claworld 0.1.4 → 0.2.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 +12 -29
- package/openclaw.plugin.json +9 -33
- package/package.json +2 -10
- package/skills/claworld-help/SKILL.md +86 -160
- package/skills/claworld-join-and-chat/SKILL.md +107 -203
- package/skills/claworld-manage-worlds/SKILL.md +75 -392
- package/src/lib/chat-request.js +347 -0
- package/src/lib/{accepted-chat-kickoff.js → relay/kickoff-text.js} +67 -26
- package/src/openclaw/index.js +0 -5
- package/src/openclaw/installer/cli.js +14 -16
- package/src/openclaw/installer/core.js +13 -14
- package/src/openclaw/installer/doctor.js +69 -31
- package/src/openclaw/installer/workspace-contract.js +33 -9
- package/src/openclaw/plugin/claworld-channel-plugin.js +156 -625
- package/src/openclaw/plugin/config-schema.js +4 -16
- package/src/openclaw/plugin/managed-config.js +127 -75
- package/src/openclaw/plugin/onboarding.js +7 -3
- package/src/openclaw/plugin/register.js +40 -339
- package/src/openclaw/plugin/relay-client.js +112 -102
- package/src/openclaw/protocol/relay-event-protocol.js +34 -22
- package/src/openclaw/runtime/canonical-result-builder.js +15 -5
- package/src/openclaw/runtime/demo-session-bootstrap.js +0 -4
- package/src/openclaw/runtime/feedback-helper.js +3 -2
- package/src/openclaw/runtime/inbound-session-router.js +28 -20
- package/src/openclaw/runtime/outbound-session-bridge.js +21 -9
- package/src/openclaw/runtime/product-shell-helper.js +45 -637
- package/src/openclaw/runtime/runtime-path.js +2 -2
- package/src/openclaw/runtime/system-message-orchestrator.js +1 -1
- package/src/openclaw/runtime/tool-contracts.js +36 -258
- package/src/openclaw/runtime/world-moderation-helper.js +11 -65
- package/src/product-shell/catalog/default-world-catalog.js +15 -33
- package/src/product-shell/contracts/candidate-feed.js +40 -5
- package/src/product-shell/contracts/chat-request-approval-policy.js +3 -3
- package/src/product-shell/contracts/world-manifest.js +134 -161
- package/src/product-shell/contracts/world-orchestration.js +55 -326
- package/src/product-shell/feedback/feedback-routes.js +4 -3
- package/src/product-shell/feedback/feedback-service.js +11 -8
- package/src/product-shell/index.js +6 -7
- package/src/product-shell/matching/matchmaking-service.js +39 -5
- package/src/product-shell/membership/membership-service.js +125 -147
- package/src/product-shell/onboarding/onboarding-service.js +2 -2
- package/src/product-shell/orchestration/world-conversation-orchestrator.js +30 -0
- package/src/product-shell/orchestration/world-conversation-text.js +231 -0
- package/src/product-shell/results/result-service.js +9 -3
- package/src/product-shell/search/search-service.js +28 -1
- package/src/product-shell/social/chat-request-routes.js +0 -1
- package/src/product-shell/social/chat-request-service.js +1 -102
- package/src/product-shell/worlds/world-admin-service.js +86 -277
- package/src/product-shell/worlds/world-authorization.js +3 -5
- package/src/product-shell/worlds/world-routes.js +8 -38
- package/src/product-shell/worlds/world-service.js +3 -3
- package/src/product-shell/worlds/world-text.js +77 -0
- package/src/lib/runtime-guidance.js +0 -457
- package/src/openclaw/runtime/world-session-startup.js +0 -1
- package/src/product-shell/orchestration/session-orchestrator.js +0 -38
|
@@ -99,7 +99,7 @@ const SINGLE_ACCOUNT_PROPERTIES = {
|
|
|
99
99
|
toolProfile: {
|
|
100
100
|
type: 'string',
|
|
101
101
|
enum: ['minimal', 'default', 'world', 'full'],
|
|
102
|
-
description: '
|
|
102
|
+
description: 'Legacy ignored field retained for backward-compatible config parsing.',
|
|
103
103
|
},
|
|
104
104
|
heartbeatSeconds: {
|
|
105
105
|
type: 'integer',
|
|
@@ -119,7 +119,7 @@ const SINGLE_ACCOUNT_PROPERTIES = {
|
|
|
119
119
|
sessionTarget: {
|
|
120
120
|
type: 'string',
|
|
121
121
|
enum: ['subagent', 'mainagent'],
|
|
122
|
-
default: '
|
|
122
|
+
default: 'mainagent',
|
|
123
123
|
},
|
|
124
124
|
fallbackTarget: {
|
|
125
125
|
type: 'string',
|
|
@@ -169,18 +169,6 @@ const SINGLE_ACCOUNT_PROPERTIES = {
|
|
|
169
169
|
description: 'Legacy alias. `true` maps to `approval.mode = "open"` and `false` maps to `approval.mode = "manual_review"`.',
|
|
170
170
|
default: false,
|
|
171
171
|
},
|
|
172
|
-
maxTurns: {
|
|
173
|
-
type: 'integer',
|
|
174
|
-
minimum: 1,
|
|
175
|
-
description: 'Legacy ignored field. Approval policy no longer carries session turn controls.',
|
|
176
|
-
default: 4,
|
|
177
|
-
},
|
|
178
|
-
turnTimeoutMs: {
|
|
179
|
-
type: 'integer',
|
|
180
|
-
minimum: 1000,
|
|
181
|
-
description: 'Legacy ignored field. Approval policy no longer carries session timeout controls.',
|
|
182
|
-
default: 30000,
|
|
183
|
-
},
|
|
184
172
|
},
|
|
185
173
|
},
|
|
186
174
|
testing: {
|
|
@@ -230,7 +218,7 @@ export const claworldChannelConfigSchema = {
|
|
|
230
218
|
description:
|
|
231
219
|
'最小 OpenClaw claworld channel 配置;支持单账号或 accounts.<id> 多账号模式。canonical flow uses appToken + registration, while relay/localAgent fields remain compatibility aliases.',
|
|
232
220
|
routingShape: {
|
|
233
|
-
sessionTarget: '
|
|
221
|
+
sessionTarget: 'mainagent',
|
|
234
222
|
fallbackTarget: 'mainagent',
|
|
235
223
|
allowHumanInterrupt: true,
|
|
236
224
|
},
|
|
@@ -344,7 +332,7 @@ export function validateClaworldChannelConfig(config = {}, accountId = null) {
|
|
|
344
332
|
errors.push({ code: 'invalid_heartbeat_seconds', value: candidate.heartbeatSeconds });
|
|
345
333
|
}
|
|
346
334
|
|
|
347
|
-
const sessionTarget = candidate.routing?.sessionTarget || '
|
|
335
|
+
const sessionTarget = candidate.routing?.sessionTarget || 'mainagent';
|
|
348
336
|
const fallbackTarget = candidate.routing?.fallbackTarget || 'mainagent';
|
|
349
337
|
if (!['subagent', 'mainagent'].includes(sessionTarget)) {
|
|
350
338
|
errors.push({ code: 'invalid_session_target', value: sessionTarget });
|
|
@@ -13,13 +13,15 @@ import {
|
|
|
13
13
|
normalizeChatRequestApprovalMode,
|
|
14
14
|
} from '../../product-shell/contracts/chat-request-approval-policy.js';
|
|
15
15
|
|
|
16
|
-
export const DEFAULT_CLAWORLD_SERVER_URL = 'https://
|
|
16
|
+
export const DEFAULT_CLAWORLD_SERVER_URL = 'https://clawold.love';
|
|
17
17
|
export const DEFAULT_CLAWORLD_API_KEY = 'local-test';
|
|
18
|
-
export const DEFAULT_CLAWORLD_AGENT_ID = '
|
|
18
|
+
export const DEFAULT_CLAWORLD_AGENT_ID = 'main';
|
|
19
19
|
export const DEFAULT_CLAWORLD_ACCOUNT_ID = 'claworld';
|
|
20
20
|
export const DEFAULT_CLAWORLD_TOOL_PROFILE = 'default';
|
|
21
21
|
export const DEFAULT_CLAWORLD_DM_SCOPE = 'per-channel-peer';
|
|
22
22
|
export const DEFAULT_CLAWORLD_APPROVAL_MODE = DEFAULT_CHAT_REQUEST_APPROVAL_POLICY_MODE;
|
|
23
|
+
export const DEFAULT_CLAWORLD_SESSION_TARGET = 'mainagent';
|
|
24
|
+
export const DEFAULT_CLAWORLD_FALLBACK_TARGET = 'mainagent';
|
|
23
25
|
|
|
24
26
|
export const TOOL_PROFILES = CLAWORLD_TOOL_PROFILES;
|
|
25
27
|
|
|
@@ -107,24 +109,61 @@ function findManagedAccountEntry(config = {}, accountId) {
|
|
|
107
109
|
return {};
|
|
108
110
|
}
|
|
109
111
|
|
|
112
|
+
function inferExistingAgentId(config = {}, accountId = DEFAULT_CLAWORLD_ACCOUNT_ID) {
|
|
113
|
+
const bindings = Array.isArray(config?.bindings) ? config.bindings : [];
|
|
114
|
+
const bindingMatch = bindings
|
|
115
|
+
.map((item) => ensureObject(item))
|
|
116
|
+
.find((item) => ensureObject(item.match).channel === 'claworld'
|
|
117
|
+
&& normalizeText(ensureObject(item.match).accountId, null) === accountId
|
|
118
|
+
&& normalizeText(item.agentId, null));
|
|
119
|
+
if (bindingMatch?.agentId) return normalizeText(bindingMatch.agentId, null);
|
|
120
|
+
|
|
121
|
+
const agents = Array.isArray(config?.agents?.list) ? config.agents.list : [];
|
|
122
|
+
if (agents.some((item) => ensureObject(item).id === DEFAULT_CLAWORLD_AGENT_ID)) {
|
|
123
|
+
return DEFAULT_CLAWORLD_AGENT_ID;
|
|
124
|
+
}
|
|
125
|
+
if (agents.length === 1) {
|
|
126
|
+
return normalizeText(ensureObject(agents[0]).id, DEFAULT_CLAWORLD_AGENT_ID);
|
|
127
|
+
}
|
|
128
|
+
return DEFAULT_CLAWORLD_AGENT_ID;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const MANAGED_LEGACY_BUNDLED_SKILL_NAMES = Object.freeze([
|
|
132
|
+
'claworld-join-and-chat',
|
|
133
|
+
'claworld-manage-worlds',
|
|
134
|
+
'claworld-help',
|
|
135
|
+
]);
|
|
136
|
+
|
|
137
|
+
function hasOnlyManagedBundledSkills(value) {
|
|
138
|
+
if (!Array.isArray(value) || value.length === 0) return false;
|
|
139
|
+
return value.every((skillName) => MANAGED_LEGACY_BUNDLED_SKILL_NAMES.includes(skillName));
|
|
140
|
+
}
|
|
141
|
+
|
|
110
142
|
function buildManagedAgentEntry(options = {}) {
|
|
111
|
-
const managedSkills = resolveManagedAgentSkills({ toolProfile: options.toolProfile });
|
|
112
143
|
return {
|
|
113
144
|
id: options.agentId,
|
|
114
145
|
workspace: options.workspace,
|
|
115
|
-
...(managedSkills === undefined ? {} : { skills: managedSkills }),
|
|
116
146
|
...(options.agentDirExplicit && options.agentDir ? { agentDir: options.agentDir } : {}),
|
|
117
147
|
};
|
|
118
148
|
}
|
|
119
149
|
|
|
150
|
+
function buildManagedRoutingEntry(options = {}, existingRouting = {}) {
|
|
151
|
+
return {
|
|
152
|
+
...ensureObject(existingRouting),
|
|
153
|
+
sessionTarget: normalizeText(options.sessionTarget, DEFAULT_CLAWORLD_SESSION_TARGET),
|
|
154
|
+
fallbackTarget: normalizeText(options.fallbackTarget, DEFAULT_CLAWORLD_FALLBACK_TARGET),
|
|
155
|
+
allowHumanInterrupt: existingRouting?.allowHumanInterrupt !== false,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
120
159
|
function buildManagedAccountEntry(options = {}) {
|
|
121
160
|
const base = {
|
|
122
161
|
enabled: true,
|
|
123
162
|
serverUrl: options.serverUrl,
|
|
124
163
|
apiKey: options.apiKey,
|
|
125
164
|
accountId: options.accountId,
|
|
126
|
-
toolProfile: options.toolProfile,
|
|
127
165
|
name: normalizeText(options.name, normalizeText(options.displayName, null)),
|
|
166
|
+
routing: buildManagedRoutingEntry(options),
|
|
128
167
|
approval: {
|
|
129
168
|
mode: normalizeChatRequestApprovalMode(options.approvalMode, DEFAULT_CLAWORLD_APPROVAL_MODE),
|
|
130
169
|
},
|
|
@@ -162,8 +201,8 @@ function buildMergedAccountEntry(existingAccount = {}, options = {}) {
|
|
|
162
201
|
serverUrl: options.serverUrl,
|
|
163
202
|
apiKey: options.apiKey,
|
|
164
203
|
accountId: options.accountId,
|
|
165
|
-
toolProfile: options.toolProfile,
|
|
166
204
|
name: normalizeText(options.name, normalizeText(existingAccount.name, normalizeText(options.displayName, null))),
|
|
205
|
+
routing: buildManagedRoutingEntry(options, existingAccount.routing),
|
|
167
206
|
approval: {
|
|
168
207
|
...existingApproval,
|
|
169
208
|
mode: normalizeChatRequestApprovalMode(options.approvalMode, DEFAULT_CLAWORLD_APPROVAL_MODE),
|
|
@@ -179,6 +218,7 @@ function buildMergedAccountEntry(existingAccount = {}, options = {}) {
|
|
|
179
218
|
? { relay: existingRelay }
|
|
180
219
|
: {}),
|
|
181
220
|
};
|
|
221
|
+
delete merged.toolProfile;
|
|
182
222
|
|
|
183
223
|
if (options.appToken) {
|
|
184
224
|
return {
|
|
@@ -344,7 +384,7 @@ ${identityLine}
|
|
|
344
384
|
|
|
345
385
|
Use this file for durable Claworld-specific notes only.
|
|
346
386
|
|
|
347
|
-
- keep world rules, pairing context, and recurring counterpart preferences here when they help future Claworld
|
|
387
|
+
- keep world rules, pairing context, and recurring counterpart preferences here when they help future Claworld conversations
|
|
348
388
|
- do not duplicate a full standalone OpenClaw bootstrap/persona here
|
|
349
389
|
- prefer channel/world-specific memory over general-purpose assistant memory
|
|
350
390
|
`;
|
|
@@ -380,15 +420,24 @@ export function resolveClaworldManagedRuntimeOptions({
|
|
|
380
420
|
overrides = {},
|
|
381
421
|
} = {}) {
|
|
382
422
|
const resolvedAccountId = normalizeText(accountId, DEFAULT_CLAWORLD_ACCOUNT_ID);
|
|
383
|
-
const
|
|
423
|
+
const attachToExistingAgent = overrides.attachToExistingAgent !== false;
|
|
424
|
+
const inferredAgentId = inferExistingAgentId(cfg, resolvedAccountId);
|
|
425
|
+
const agentId = normalizeText(overrides.agentId, inferredAgentId);
|
|
384
426
|
const existingAgent = findAgentEntry(cfg, agentId);
|
|
385
427
|
const existingAccount = findManagedAccountEntry(cfg, resolvedAccountId);
|
|
386
428
|
const replaceManagedRuntime = overrides.replaceManagedRuntime !== false;
|
|
387
|
-
const
|
|
429
|
+
const explicitWorkspace = normalizeText(overrides.workspace, null);
|
|
430
|
+
const manageAgentEntry = overrides.manageAgentEntry === true
|
|
431
|
+
|| overrides.agentDirExplicit === true
|
|
432
|
+
|| attachToExistingAgent !== true;
|
|
433
|
+
const manageWorkspace = overrides.manageWorkspace === true
|
|
434
|
+
|| Boolean(explicitWorkspace)
|
|
435
|
+
|| attachToExistingAgent !== true;
|
|
436
|
+
const defaultWorkspace = manageWorkspace ? resolveDefaultManagedWorkspace(agentId) : null;
|
|
388
437
|
const workspace = normalizeText(
|
|
389
|
-
|
|
438
|
+
explicitWorkspace,
|
|
390
439
|
replaceManagedRuntime
|
|
391
|
-
? defaultWorkspace
|
|
440
|
+
? normalizeText(existingAgent?.workspace, defaultWorkspace)
|
|
392
441
|
: normalizeText(existingAgent?.workspace, defaultWorkspace),
|
|
393
442
|
);
|
|
394
443
|
const serverUrl = normalizeText(
|
|
@@ -421,10 +470,6 @@ export function resolveClaworldManagedRuntimeOptions({
|
|
|
421
470
|
normalizeText(input.name, resolveDefaultManagedDisplayName(resolvedAccountId)),
|
|
422
471
|
);
|
|
423
472
|
const name = normalizeText(overrides.name, displayName);
|
|
424
|
-
const explicitToolProfile = normalizeText(
|
|
425
|
-
overrides.toolProfile,
|
|
426
|
-
normalizeText(input.toolProfile, null),
|
|
427
|
-
);
|
|
428
473
|
const existingRegistrationAgentCode = normalizeRegistrationAgentCode(
|
|
429
474
|
existingAccount?.registration?.agentCode,
|
|
430
475
|
normalizeRegistrationAgentCode(existingAccount?.localAgent?.agentCode, null),
|
|
@@ -449,9 +494,12 @@ export function resolveClaworldManagedRuntimeOptions({
|
|
|
449
494
|
|
|
450
495
|
return {
|
|
451
496
|
repoRoot: normalizeText(overrides.repoRoot, null),
|
|
497
|
+
attachToExistingAgent,
|
|
452
498
|
agentId,
|
|
453
499
|
accountId: resolvedAccountId,
|
|
454
500
|
workspace,
|
|
501
|
+
manageAgentEntry,
|
|
502
|
+
manageWorkspace,
|
|
455
503
|
agentDir: normalizeText(overrides.agentDir, null),
|
|
456
504
|
agentDirExplicit: overrides.agentDirExplicit === true,
|
|
457
505
|
serverUrl,
|
|
@@ -461,11 +509,6 @@ export function resolveClaworldManagedRuntimeOptions({
|
|
|
461
509
|
displayName,
|
|
462
510
|
name,
|
|
463
511
|
defaultToAddress: normalizeText(overrides.defaultToAddress, null),
|
|
464
|
-
toolProfile: resolveManagedToolProfile({
|
|
465
|
-
cfg,
|
|
466
|
-
existingAccount,
|
|
467
|
-
explicitToolProfile,
|
|
468
|
-
}),
|
|
469
512
|
approvalMode,
|
|
470
513
|
sessionDmScope: normalizeText(
|
|
471
514
|
overrides.sessionDmScope,
|
|
@@ -476,37 +519,45 @@ export function resolveClaworldManagedRuntimeOptions({
|
|
|
476
519
|
forceDefaultAccount: overrides.forceDefaultAccount === true,
|
|
477
520
|
pluginInstallMode: normalizeText(overrides.pluginInstallMode, 'skip'),
|
|
478
521
|
installPlugin: overrides.installPlugin !== false,
|
|
522
|
+
sessionTarget: normalizeText(overrides.sessionTarget, DEFAULT_CLAWORLD_SESSION_TARGET),
|
|
523
|
+
fallbackTarget: normalizeText(overrides.fallbackTarget, DEFAULT_CLAWORLD_FALLBACK_TARGET),
|
|
479
524
|
};
|
|
480
525
|
}
|
|
481
526
|
|
|
482
527
|
export function applyClaworldManagedRuntimeConfig(inputConfig = {}, options = {}) {
|
|
483
528
|
const config = JSON.parse(JSON.stringify(ensureObject(inputConfig)));
|
|
484
|
-
const toolProfile = normalizeClaworldToolProfile(options.toolProfile);
|
|
485
|
-
const toolNames = resolveToolNames({ toolProfile });
|
|
486
529
|
const summary = [];
|
|
487
530
|
const replaceManagedRuntime = options.replaceManagedRuntime !== false;
|
|
488
531
|
const preserveDefaultAccount = options.preserveDefaultAccount === true;
|
|
489
532
|
const sessionDmScope = normalizeText(options.sessionDmScope, DEFAULT_CLAWORLD_DM_SCOPE);
|
|
533
|
+
const manageAgentEntry = options.manageAgentEntry === true;
|
|
490
534
|
|
|
491
535
|
if (!options.appToken && !normalizeText(options.registrationAgentCode, null)) {
|
|
492
536
|
throw new Error('claworld registration agentCode is required when appToken is absent');
|
|
493
537
|
}
|
|
494
538
|
|
|
495
|
-
config.tools = ensureObject(config.tools);
|
|
496
539
|
const removedManagedToolNames = new Set([
|
|
540
|
+
...CLAWORLD_PUBLIC_TOOL_NAMES,
|
|
497
541
|
...CLAWORLD_COMPATIBILITY_TOOL_NAMES,
|
|
498
542
|
...CLAWORLD_RETIRED_PUBLIC_TOOL_NAMES,
|
|
499
543
|
]);
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
544
|
+
if (inputConfig?.tools && typeof inputConfig.tools === 'object') {
|
|
545
|
+
config.tools = ensureObject(config.tools);
|
|
546
|
+
const existingAllow = asStringArray(config.tools.allow);
|
|
547
|
+
const filteredAllow = existingAllow.filter((toolName) => !removedManagedToolNames.has(toolName));
|
|
548
|
+
const removedManagedTools = existingAllow.filter((toolName) => removedManagedToolNames.has(toolName));
|
|
549
|
+
if (removedManagedTools.length > 0) {
|
|
550
|
+
if (filteredAllow.length > 0) {
|
|
551
|
+
config.tools.allow = uniqueStrings(filteredAllow);
|
|
552
|
+
} else {
|
|
553
|
+
delete config.tools.allow;
|
|
554
|
+
}
|
|
555
|
+
summary.push(`tools.allow removed managed claworld entries (${removedManagedTools.join(',')})`);
|
|
556
|
+
}
|
|
557
|
+
if (Object.keys(config.tools).length === 0) {
|
|
558
|
+
delete config.tools;
|
|
559
|
+
}
|
|
508
560
|
}
|
|
509
|
-
summary.push(`tools.allow updated for ${toolProfile} profile (${describeToolAllowEntries(toolNames)})`);
|
|
510
561
|
|
|
511
562
|
config.session = ensureObject(config.session);
|
|
512
563
|
if (!Object.prototype.hasOwnProperty.call(config.session, 'dmScope')) {
|
|
@@ -516,51 +567,53 @@ export function applyClaworldManagedRuntimeConfig(inputConfig = {}, options = {}
|
|
|
516
567
|
|
|
517
568
|
config.agents = ensureObject(config.agents);
|
|
518
569
|
const existingAgentList = Array.isArray(config.agents.list) ? [...config.agents.list] : [];
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
} else {
|
|
532
|
-
const agentIndex = findAgentIndex(existingAgentList, options.agentId);
|
|
533
|
-
if (agentIndex >= 0) {
|
|
534
|
-
const existingAgent = ensureObject(existingAgentList[agentIndex]);
|
|
535
|
-
const existingAgentDir = normalizeText(existingAgent.agentDir, null);
|
|
536
|
-
const managedSkills = resolveManagedAgentSkills({ toolProfile: options.toolProfile });
|
|
537
|
-
const keepExistingAgentDir = Boolean(
|
|
538
|
-
existingAgentDir
|
|
539
|
-
&& (
|
|
540
|
-
options.agentDirExplicit
|
|
541
|
-
|| existingAgentDir !== normalizeText(options.agentDir, null)
|
|
542
|
-
),
|
|
570
|
+
if (manageAgentEntry) {
|
|
571
|
+
const managedAgentEntry = buildManagedAgentEntry(options);
|
|
572
|
+
if (replaceManagedRuntime) {
|
|
573
|
+
const removedAgentEntries = existingAgentList.filter((item) => ensureObject(item).id === options.agentId).length;
|
|
574
|
+
config.agents.list = [
|
|
575
|
+
...existingAgentList.filter((item) => ensureObject(item).id !== options.agentId),
|
|
576
|
+
managedAgentEntry,
|
|
577
|
+
];
|
|
578
|
+
summary.push(
|
|
579
|
+
removedAgentEntries > 0
|
|
580
|
+
? `replaced managed agent entry ${options.agentId}`
|
|
581
|
+
: `added workspace-scoped agent entry ${options.agentId}`,
|
|
543
582
|
);
|
|
544
|
-
const nextAgentEntry = {
|
|
545
|
-
...existingAgent,
|
|
546
|
-
id: options.agentId,
|
|
547
|
-
workspace: normalizeText(existingAgent.workspace, options.workspace),
|
|
548
|
-
...(keepExistingAgentDir ? { agentDir: existingAgentDir } : {}),
|
|
549
|
-
...(managedSkills === undefined ? {} : { skills: managedSkills }),
|
|
550
|
-
};
|
|
551
|
-
if (!keepExistingAgentDir) {
|
|
552
|
-
delete nextAgentEntry.agentDir;
|
|
553
|
-
}
|
|
554
|
-
if (managedSkills === undefined) {
|
|
555
|
-
delete nextAgentEntry.skills;
|
|
556
|
-
}
|
|
557
|
-
existingAgentList[agentIndex] = nextAgentEntry;
|
|
558
|
-
summary.push(`updated existing agent entry ${options.agentId}`);
|
|
559
583
|
} else {
|
|
560
|
-
existingAgentList.
|
|
561
|
-
|
|
584
|
+
const agentIndex = findAgentIndex(existingAgentList, options.agentId);
|
|
585
|
+
if (agentIndex >= 0) {
|
|
586
|
+
const existingAgent = ensureObject(existingAgentList[agentIndex]);
|
|
587
|
+
const existingAgentDir = normalizeText(existingAgent.agentDir, null);
|
|
588
|
+
const keepExistingAgentDir = Boolean(
|
|
589
|
+
existingAgentDir
|
|
590
|
+
&& (
|
|
591
|
+
options.agentDirExplicit
|
|
592
|
+
|| existingAgentDir !== normalizeText(options.agentDir, null)
|
|
593
|
+
),
|
|
594
|
+
);
|
|
595
|
+
const nextAgentEntry = {
|
|
596
|
+
...existingAgent,
|
|
597
|
+
id: options.agentId,
|
|
598
|
+
workspace: normalizeText(existingAgent.workspace, options.workspace),
|
|
599
|
+
...(keepExistingAgentDir ? { agentDir: existingAgentDir } : {}),
|
|
600
|
+
};
|
|
601
|
+
if (!keepExistingAgentDir) {
|
|
602
|
+
delete nextAgentEntry.agentDir;
|
|
603
|
+
}
|
|
604
|
+
if (hasOnlyManagedBundledSkills(existingAgent.skills)) {
|
|
605
|
+
delete nextAgentEntry.skills;
|
|
606
|
+
}
|
|
607
|
+
existingAgentList[agentIndex] = nextAgentEntry;
|
|
608
|
+
summary.push(`updated existing agent entry ${options.agentId}`);
|
|
609
|
+
} else {
|
|
610
|
+
existingAgentList.push(managedAgentEntry);
|
|
611
|
+
summary.push(`added workspace-scoped agent entry ${options.agentId}`);
|
|
612
|
+
}
|
|
613
|
+
config.agents.list = existingAgentList;
|
|
562
614
|
}
|
|
563
|
-
|
|
615
|
+
} else {
|
|
616
|
+
summary.push(`attached claworld account ${options.accountId} to existing local agent ${options.agentId}`);
|
|
564
617
|
}
|
|
565
618
|
|
|
566
619
|
config.channels = ensureObject(config.channels);
|
|
@@ -619,7 +672,6 @@ export function applyClaworldManagedRuntimeConfig(inputConfig = {}, options = {}
|
|
|
619
672
|
|
|
620
673
|
return {
|
|
621
674
|
config,
|
|
622
|
-
toolNames,
|
|
623
675
|
summary,
|
|
624
676
|
canonicalAgentCode: canonicalRelayAgentCode(
|
|
625
677
|
options.registrationAgentCode,
|
|
@@ -200,15 +200,19 @@ async function applyManagedOnboardingConfig({
|
|
|
200
200
|
} = {}) {
|
|
201
201
|
const managedOptions = resolveManagedOptionsFromContext({ cfg, accountId, input });
|
|
202
202
|
const next = applyClaworldManagedRuntimeConfig(cfg, managedOptions);
|
|
203
|
-
|
|
203
|
+
if (managedOptions.manageWorkspace) {
|
|
204
|
+
await ensureManagedWorkspaceSeed(managedOptions);
|
|
205
|
+
}
|
|
204
206
|
|
|
205
207
|
const noteLines = [
|
|
206
|
-
`
|
|
208
|
+
`Bound local agent/account: ${managedOptions.agentId}`,
|
|
207
209
|
`Remote backend: ${managedOptions.serverUrl}`,
|
|
208
210
|
managedOptions.registrationAgentCode
|
|
209
211
|
? `Bootstrap mode: registration (${managedOptions.registrationAgentCode})`
|
|
210
212
|
: 'Bootstrap mode: appToken/manual binding',
|
|
211
|
-
|
|
213
|
+
managedOptions.manageWorkspace
|
|
214
|
+
? 'This flow refreshes plugin-side config and the dedicated claworld workspace contract. It does not start a backend service.'
|
|
215
|
+
: 'This flow refreshes plugin-side config and binds claworld onto the existing local agent. It does not start a backend service.',
|
|
212
216
|
];
|
|
213
217
|
await prompter.note(
|
|
214
218
|
noteLines.join('\n'),
|