@xfxstudio/claworld 2026.4.14-testing.1 → 2026.4.16-testing.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.
Files changed (47) hide show
  1. package/openclaw.plugin.json +1 -1
  2. package/package.json +1 -1
  3. package/index.js +0 -50
  4. package/setup-entry.js +0 -6
  5. package/skills/claworld-a2a-channel-agent/SKILL.md +0 -218
  6. package/skills/claworld-help/SKILL.md +0 -304
  7. package/skills/claworld-join-and-chat/SKILL.md +0 -515
  8. package/skills/claworld-manage-worlds/SKILL.md +0 -283
  9. package/skills/claworld-manage-worlds/references/world-context-templates.md +0 -145
  10. package/src/lib/chat-request.js +0 -366
  11. package/src/lib/public-identity.js +0 -175
  12. package/src/lib/relay/agent-readable-markdown.js +0 -385
  13. package/src/lib/relay/kickoff-progress.js +0 -162
  14. package/src/lib/relay/kickoff-text.js +0 -191
  15. package/src/lib/relay/shared.js +0 -30
  16. package/src/lib/runtime-errors.js +0 -149
  17. package/src/openclaw/index.js +0 -51
  18. package/src/openclaw/plugin/account-identity.js +0 -73
  19. package/src/openclaw/plugin/claworld-channel-plugin.js +0 -3483
  20. package/src/openclaw/plugin/config-schema.js +0 -392
  21. package/src/openclaw/plugin/lifecycle.js +0 -114
  22. package/src/openclaw/plugin/managed-config.js +0 -1054
  23. package/src/openclaw/plugin/onboarding.js +0 -312
  24. package/src/openclaw/plugin/register-tooling.js +0 -728
  25. package/src/openclaw/plugin/register.js +0 -1609
  26. package/src/openclaw/plugin/relay-client-shared.js +0 -146
  27. package/src/openclaw/plugin/relay-client.js +0 -1469
  28. package/src/openclaw/plugin/runtime-backup.js +0 -105
  29. package/src/openclaw/plugin/runtime.js +0 -12
  30. package/src/openclaw/plugin-version.js +0 -67
  31. package/src/openclaw/protocol/relay-event-protocol.js +0 -43
  32. package/src/openclaw/runtime/backend-error-context.js +0 -91
  33. package/src/openclaw/runtime/canonical-result-builder.js +0 -126
  34. package/src/openclaw/runtime/demo-session-bootstrap.js +0 -32
  35. package/src/openclaw/runtime/feedback-helper.js +0 -145
  36. package/src/openclaw/runtime/inbound-session-router.js +0 -44
  37. package/src/openclaw/runtime/outbound-session-bridge.js +0 -29
  38. package/src/openclaw/runtime/product-shell-helper.js +0 -931
  39. package/src/openclaw/runtime/runtime-path.js +0 -19
  40. package/src/openclaw/runtime/system-message-orchestrator.js +0 -1
  41. package/src/openclaw/runtime/tool-contracts.js +0 -939
  42. package/src/openclaw/runtime/tool-inventory.js +0 -83
  43. package/src/openclaw/runtime/world-membership-helper.js +0 -320
  44. package/src/openclaw/runtime/world-moderation-helper.js +0 -508
  45. package/src/product-shell/contracts/chat-request-approval-policy.js +0 -93
  46. package/src/product-shell/contracts/world-orchestration.js +0 -734
  47. package/src/product-shell/orchestration/world-conversation-text.js +0 -229
@@ -1,392 +0,0 @@
1
- import {
2
- applyRuntimeIdentity,
3
- normalizeRuntimeRegistration,
4
- resolveRuntimeAppToken,
5
- } from './account-identity.js';
6
-
7
- const REQUIRED_KEYS = ['enabled', 'serverUrl', 'apiKey', 'accountId'];
8
-
9
- export const CLAWORLD_CHANNEL_ID = 'claworld';
10
-
11
- const AGENT_REGISTRATION_SCHEMA = {
12
- type: 'object',
13
- additionalProperties: false,
14
- properties: {
15
- enabled: {
16
- type: 'boolean',
17
- description: 'Enable relay agent registration when this account does not already have an app token.',
18
- default: false,
19
- },
20
- displayName: {
21
- type: 'string',
22
- minLength: 1,
23
- description: 'Public display name to use when the relay agent is created or refreshed.',
24
- },
25
- },
26
- };
27
-
28
- export const LOCAL_AGENT_BOOTSTRAP_SCHEMA = AGENT_REGISTRATION_SCHEMA;
29
- export const LOCAL_AGENT_BOOTSTRAP_REQUIRED = ['displayName'];
30
-
31
- export const MANUAL_RELAY_BINDING_SCHEMA = {
32
- type: 'object',
33
- additionalProperties: false,
34
- properties: {
35
- appToken: {
36
- type: 'string',
37
- minLength: 1,
38
- description: 'Canonical Claworld app token for this account. The runtime resolves the bound relay agent from this token.',
39
- },
40
- agentId: {
41
- type: 'string',
42
- minLength: 1,
43
- description: 'Legacy relay agent id hint. Canonical flow resolves the binding from appToken at runtime.',
44
- },
45
- credentialToken: {
46
- type: 'string',
47
- minLength: 1,
48
- description: 'Legacy alias for appToken.',
49
- },
50
- defaultTargetAgentId: {
51
- type: 'string',
52
- minLength: 1,
53
- description: 'Default relay target agentId for minimal outbound testing.',
54
- },
55
- },
56
- };
57
-
58
- const SINGLE_ACCOUNT_PROPERTIES = {
59
- name: {
60
- type: 'string',
61
- minLength: 1,
62
- description: 'Optional operator-facing name for this local Claworld account.',
63
- },
64
- enabled: { type: 'boolean', description: 'Enable the Claworld channel plugin.' },
65
- serverUrl: {
66
- type: 'string',
67
- minLength: 1,
68
- description: 'Relay backend base URL or websocket URL (http/https/ws/wss).',
69
- },
70
- apiKey: {
71
- type: 'string',
72
- minLength: 1,
73
- description: 'Plugin/backend API key for future backend-authenticated control paths.',
74
- },
75
- appToken: {
76
- type: 'string',
77
- minLength: 1,
78
- description: 'Canonical Claworld app token for this channel account.',
79
- },
80
- accountId: {
81
- type: 'string',
82
- minLength: 1,
83
- description: 'Local OpenClaw-facing account id bound to this channel instance.',
84
- },
85
- toolProfile: {
86
- type: 'string',
87
- enum: ['minimal', 'default', 'world', 'full'],
88
- description: 'Legacy ignored field retained for backward-compatible config parsing.',
89
- },
90
- heartbeatSeconds: {
91
- type: 'integer',
92
- minimum: 1,
93
- description: 'Heartbeat cadence for the relay websocket client.',
94
- default: 15,
95
- },
96
- reconnect: {
97
- type: 'boolean',
98
- description: 'Whether reconnect attempts are allowed after disconnect.',
99
- default: true,
100
- },
101
- routing: {
102
- type: 'object',
103
- additionalProperties: false,
104
- properties: {
105
- sessionTarget: {
106
- type: 'string',
107
- enum: ['subagent', 'mainagent'],
108
- default: 'mainagent',
109
- },
110
- fallbackTarget: {
111
- type: 'string',
112
- enum: ['mainagent', 'human(optional)'],
113
- default: 'mainagent',
114
- },
115
- allowHumanInterrupt: {
116
- type: 'boolean',
117
- default: true,
118
- },
119
- },
120
- },
121
- testing: {
122
- type: 'object',
123
- additionalProperties: false,
124
- properties: {
125
- allowBridgedCommandDispatch: {
126
- type: 'boolean',
127
- description: 'Test-only switch that allows bridged relay turns beginning with slash commands to use the OpenClaw command fast-path.',
128
- default: false,
129
- },
130
- },
131
- },
132
- registration: AGENT_REGISTRATION_SCHEMA,
133
- relay: MANUAL_RELAY_BINDING_SCHEMA,
134
- };
135
-
136
- export const claworldChannelConfigJsonSchema = {
137
- type: 'object',
138
- additionalProperties: false,
139
- properties: {
140
- ...SINGLE_ACCOUNT_PROPERTIES,
141
- defaultAccount: {
142
- type: 'string',
143
- minLength: 1,
144
- description: 'Default account id to use when multiple claworld accounts are configured.',
145
- },
146
- accounts: {
147
- type: 'object',
148
- minProperties: 1,
149
- additionalProperties: {
150
- type: 'object',
151
- additionalProperties: false,
152
- required: REQUIRED_KEYS,
153
- properties: SINGLE_ACCOUNT_PROPERTIES,
154
- },
155
- },
156
- },
157
- };
158
-
159
- export const claworldChannelConfigSchema = {
160
- channelId: CLAWORLD_CHANNEL_ID,
161
- required: REQUIRED_KEYS,
162
- optional: ['name', 'heartbeatSeconds', 'reconnect', 'routing', 'testing', 'appToken', 'registration', 'relay', 'toolProfile', 'defaultAccount', 'accounts'],
163
- jsonSchema: claworldChannelConfigJsonSchema,
164
- description:
165
- '最小 OpenClaw claworld channel 配置;支持单账号或 accounts.<id> 多账号模式。canonical flow uses appToken + registration.displayName bootstrap.',
166
- routingShape: {
167
- sessionTarget: 'mainagent',
168
- fallbackTarget: 'mainagent',
169
- allowHumanInterrupt: true,
170
- },
171
- };
172
-
173
- function normalizeText(value, fallback = null) {
174
- if (value == null) return fallback;
175
- const normalized = String(value).trim();
176
- return normalized || fallback;
177
- }
178
-
179
- function readRawClaworldRoot(config = {}) {
180
- if (config?.channels?.[CLAWORLD_CHANNEL_ID]) return config.channels[CLAWORLD_CHANNEL_ID];
181
- if (config?.[CLAWORLD_CHANNEL_ID]) return config[CLAWORLD_CHANNEL_ID];
182
- return config;
183
- }
184
-
185
- function listConfiguredClaworldAccountIds(config = {}) {
186
- const root = readRawClaworldRoot(config);
187
- if (root?.accounts && typeof root.accounts === 'object') {
188
- return Object.keys(root.accounts).filter(Boolean);
189
- }
190
- const single = root;
191
- if (single?.accountId) return [single.accountId];
192
- return [];
193
- }
194
-
195
- function readDefaultAccountId(config = {}) {
196
- const root = readRawClaworldRoot(config);
197
- const configuredIds = listConfiguredClaworldAccountIds(config);
198
- const explicit = String(root?.defaultAccount || '').trim();
199
- if (explicit && configuredIds.includes(explicit)) return explicit;
200
- if (root?.accounts?.default) return 'default';
201
- return configuredIds[0] || null;
202
- }
203
-
204
- function readClaworldConfigSection(config = {}, accountId = null) {
205
- const root = readRawClaworldRoot(config);
206
- if (root?.accounts && typeof root.accounts === 'object') {
207
- const normalizedAccountId = String(accountId || '').trim();
208
- if (normalizedAccountId && root.accounts[normalizedAccountId]) return root.accounts[normalizedAccountId];
209
-
210
- const defaultAccountId = readDefaultAccountId(config);
211
- if (defaultAccountId && root.accounts[defaultAccountId]) return root.accounts[defaultAccountId];
212
-
213
- const [firstAccount] = Object.values(root.accounts);
214
- if (firstAccount) return firstAccount;
215
- }
216
- return root;
217
- }
218
-
219
- function determineCredentialStatus(candidate = {}) {
220
- if (resolveRuntimeAppToken(candidate)) {
221
- return { tokenSource: 'config', tokenStatus: 'available' };
222
- }
223
- if (normalizeRuntimeRegistration(candidate).enabled) {
224
- return { tokenSource: 'registration', tokenStatus: 'registration_required' };
225
- }
226
- return { tokenSource: 'none', tokenStatus: 'missing' };
227
- }
228
-
229
- function determineBindingStatus(candidate = {}) {
230
- if (resolveRuntimeAppToken(candidate)) return 'bound';
231
- if (normalizeRuntimeRegistration(candidate).enabled) return 'registration_pending';
232
- return 'unbound';
233
- }
234
-
235
- export function validateClaworldChannelConfig(config = {}, accountId = null) {
236
- const root = readRawClaworldRoot(config);
237
- const candidate = readClaworldConfigSection(config, accountId) || {};
238
- const missing = REQUIRED_KEYS.filter((key) => candidate[key] == null || candidate[key] === '');
239
- const errors = [];
240
- const registration = normalizeRuntimeRegistration(candidate);
241
- const appToken = resolveRuntimeAppToken(candidate);
242
- const configuredIds = listConfiguredClaworldAccountIds(config);
243
- const hasMultipleAccounts = configuredIds.length > 1;
244
- const explicitDefaultAccount = String(root?.defaultAccount || '').trim();
245
-
246
- if (hasMultipleAccounts && !explicitDefaultAccount && !String(accountId || '').trim()) {
247
- errors.push({ code: 'missing_default_account' });
248
- }
249
- if (explicitDefaultAccount && root?.accounts && !root.accounts[explicitDefaultAccount]) {
250
- errors.push({ code: 'invalid_default_account', value: explicitDefaultAccount });
251
- }
252
-
253
- if (missing.length > 0) {
254
- errors.push({ code: 'missing_required_keys', keys: missing });
255
- }
256
-
257
- if (candidate.serverUrl != null) {
258
- try {
259
- const parsed = new URL(candidate.serverUrl);
260
- if (!['ws:', 'wss:', 'http:', 'https:'].includes(parsed.protocol)) {
261
- errors.push({ code: 'invalid_server_url_protocol', value: parsed.protocol });
262
- }
263
- } catch {
264
- errors.push({ code: 'invalid_server_url', value: candidate.serverUrl });
265
- }
266
- }
267
-
268
- if (
269
- candidate.heartbeatSeconds != null
270
- && (!Number.isFinite(Number(candidate.heartbeatSeconds)) || Number(candidate.heartbeatSeconds) <= 0)
271
- ) {
272
- errors.push({ code: 'invalid_heartbeat_seconds', value: candidate.heartbeatSeconds });
273
- }
274
-
275
- const sessionTarget = candidate.routing?.sessionTarget || 'mainagent';
276
- const fallbackTarget = candidate.routing?.fallbackTarget || 'mainagent';
277
- if (!['subagent', 'mainagent'].includes(sessionTarget)) {
278
- errors.push({ code: 'invalid_session_target', value: sessionTarget });
279
- }
280
- if (!['mainagent', 'human(optional)'].includes(fallbackTarget)) {
281
- errors.push({ code: 'invalid_fallback_target', value: fallbackTarget });
282
- }
283
-
284
- if (registration.enabled && !registration.displayName) {
285
- errors.push({ code: 'missing_registration_display_name' });
286
- }
287
-
288
- if (candidate.relay?.agentId && !appToken) {
289
- errors.push({ code: 'missing_relay_app_token' });
290
- }
291
-
292
- const runtimeIdentity = applyRuntimeIdentity({
293
- enabled: Boolean(candidate.enabled),
294
- serverUrl: candidate.serverUrl || null,
295
- apiKey: candidate.apiKey || null,
296
- appToken,
297
- accountId: candidate.accountId || null,
298
- defaultAccount: explicitDefaultAccount || null,
299
- heartbeatSeconds: candidate.heartbeatSeconds == null ? 15 : Math.floor(Number(candidate.heartbeatSeconds)),
300
- reconnect: candidate.reconnect !== false,
301
- routing: {
302
- sessionTarget,
303
- fallbackTarget,
304
- allowHumanInterrupt: candidate.routing?.allowHumanInterrupt !== false,
305
- },
306
- testing: {
307
- allowBridgedCommandDispatch: candidate.testing?.allowBridgedCommandDispatch === true,
308
- },
309
- registration,
310
- relay: {
311
- agentId: candidate.relay?.agentId || null,
312
- appToken,
313
- credentialToken: appToken,
314
- defaultTargetAgentId: candidate.relay?.defaultTargetAgentId || null,
315
- },
316
- });
317
-
318
- return {
319
- ok: errors.length === 0,
320
- errors,
321
- normalized: runtimeIdentity,
322
- };
323
- }
324
-
325
- export function inspectClaworldChannelAccount(config = {}, accountId = null) {
326
- const result = validateClaworldChannelConfig(config, accountId);
327
- const normalized = result.normalized;
328
- const configuredIds = listConfiguredClaworldAccountIds(config);
329
- const { tokenSource, tokenStatus } = determineCredentialStatus(normalized);
330
- const bindingStatus = determineBindingStatus(normalized);
331
- const configured = Boolean(normalized.serverUrl && normalized.apiKey && normalized.accountId);
332
- return {
333
- accountId: normalized.accountId || accountId || readDefaultAccountId(config) || configuredIds[0] || 'default',
334
- name: normalizeText(normalized.name, normalizeText(normalized.registration?.displayName, null)),
335
- enabled: normalized.enabled,
336
- configured,
337
- configuredStatus: configured ? 'configured' : 'missing_required_config',
338
- serverUrl: normalized.serverUrl,
339
- heartbeatSeconds: normalized.heartbeatSeconds,
340
- reconnect: normalized.reconnect,
341
- routing: normalized.routing,
342
- testing: normalized.testing,
343
- appToken: normalized.appToken || null,
344
- registration: normalized.registration,
345
- relay: normalized.relay,
346
- defaultAccount: normalized.defaultAccount,
347
- bindingStatus,
348
- tokenSource,
349
- tokenStatus,
350
- issues: result.errors,
351
- };
352
- }
353
-
354
- export function projectClaworldStatusAccount(inspection = {}) {
355
- // Keep the steady-state credential nested under relay/runtimeConfig so
356
- // generic OpenClaw status does not misclassify Claworld as a bot+app token
357
- // channel.
358
- const { appToken: _appToken, ...statusAccount } = inspection || {};
359
- return statusAccount;
360
- }
361
-
362
- export function resolveClaworldRuntimeConfig(config = {}, accountId = null) {
363
- const result = validateClaworldChannelConfig(config, accountId);
364
- if (!result.ok) {
365
- const detail = result.errors.map((error) => error.code).join(', ') || 'invalid_config';
366
- throw new Error(`invalid claworld config: ${detail}`);
367
- }
368
- return {
369
- ...result.normalized,
370
- accountId: result.normalized.accountId || accountId || readDefaultAccountId(config) || 'default',
371
- relay: result.normalized.relay,
372
- };
373
- }
374
-
375
- export function resolveClaworldChannelAccount(config = {}, accountId = null) {
376
- const runtimeConfig = resolveClaworldRuntimeConfig(config, accountId);
377
- const inspection = inspectClaworldChannelAccount(config, accountId);
378
- return {
379
- ...projectClaworldStatusAccount(inspection),
380
- runtimeReady: true,
381
- resolvedFrom: accountId ? 'requested_account' : 'default_account',
382
- runtimeConfig,
383
- };
384
- }
385
-
386
- export function listClaworldAccountIds(config = {}) {
387
- return listConfiguredClaworldAccountIds(config);
388
- }
389
-
390
- export function defaultClaworldAccountId(config = {}) {
391
- return readDefaultAccountId(config) || 'default';
392
- }
@@ -1,114 +0,0 @@
1
- import {
2
- logRuntimeBoundary,
3
- serializeRuntimeBoundaryError,
4
- } from '../../lib/runtime-errors.js';
5
-
6
- export function createClaworldLifecycleManager({ connect, disconnect, logger = console } = {}) {
7
- let started = false;
8
- let connection = null;
9
- let lastStartError = null;
10
- let lastStartFailure = null;
11
- let lastStopReason = null;
12
-
13
- return {
14
- async start(context = {}) {
15
- if (started) {
16
- logger.warn?.('[openclaw:lifecycle] start ignored: already started');
17
- return {
18
- started: true,
19
- reused: true,
20
- connection,
21
- lastStartError,
22
- lastStartFailure,
23
- lastStopReason,
24
- };
25
- }
26
-
27
- started = true;
28
- lastStartError = null;
29
- lastStartFailure = null;
30
- lastStopReason = null;
31
-
32
- try {
33
- connection = (await connect?.(context)) || null;
34
- logger.info?.('[openclaw:lifecycle] started');
35
- return {
36
- started: true,
37
- reused: false,
38
- connection,
39
- lastStartError,
40
- lastStartFailure,
41
- lastStopReason,
42
- };
43
- } catch (error) {
44
- started = false;
45
- connection = null;
46
- const normalized = logRuntimeBoundary(logger, '[openclaw:lifecycle] start failed', error, null, {
47
- includeStack: false,
48
- fallback: {
49
- code: 'openclaw_lifecycle_start_failed',
50
- category: 'bootstrap',
51
- publicMessage: 'OpenClaw Claworld lifecycle start failed',
52
- recoverable: true,
53
- },
54
- });
55
- lastStartError = normalized.message;
56
- lastStartFailure = serializeRuntimeBoundaryError(normalized);
57
- throw normalized;
58
- }
59
- },
60
- async stop(reason = 'manual_stop') {
61
- if (!started) {
62
- return {
63
- started: false,
64
- stopped: false,
65
- reason: 'not_started',
66
- lastStartError,
67
- lastStartFailure,
68
- lastStopReason,
69
- };
70
- }
71
-
72
- started = false;
73
- try {
74
- await disconnect?.({ reason, connection });
75
- } catch (error) {
76
- connection = null;
77
- const normalized = logRuntimeBoundary(logger, '[openclaw:lifecycle] stop failed', error, { reason }, {
78
- includeStack: false,
79
- fallback: {
80
- code: 'openclaw_lifecycle_stop_failed',
81
- category: 'runtime',
82
- publicMessage: 'OpenClaw Claworld lifecycle stop failed',
83
- recoverable: true,
84
- },
85
- });
86
- throw normalized;
87
- }
88
- connection = null;
89
- lastStopReason = reason;
90
- logger.info?.(`[openclaw:lifecycle] stopped (${reason})`);
91
- return {
92
- started: false,
93
- stopped: true,
94
- reason,
95
- lastStartError,
96
- lastStartFailure,
97
- lastStopReason,
98
- };
99
- },
100
- async reconnect(context = {}) {
101
- await this.stop('reconnect');
102
- return this.start(context);
103
- },
104
- snapshot() {
105
- return {
106
- started,
107
- hasConnection: Boolean(connection),
108
- lastStartError,
109
- lastStartFailure,
110
- lastStopReason,
111
- };
112
- },
113
- };
114
- }