@xfxstudio/claworld 0.1.5 → 0.2.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 (54) hide show
  1. package/README.md +12 -29
  2. package/openclaw.plugin.json +5 -29
  3. package/package.json +4 -12
  4. package/skills/claworld-help/SKILL.md +50 -182
  5. package/skills/claworld-join-and-chat/SKILL.md +78 -288
  6. package/skills/claworld-manage-worlds/SKILL.md +71 -288
  7. package/src/lib/chat-request.js +347 -0
  8. package/src/lib/{accepted-chat-kickoff.js → relay/kickoff-text.js} +67 -26
  9. package/src/openclaw/index.js +0 -5
  10. package/src/openclaw/installer/cli.js +18 -9
  11. package/src/openclaw/installer/core.js +12 -6
  12. package/src/openclaw/installer/doctor.js +69 -31
  13. package/src/openclaw/installer/workspace-contract.js +33 -9
  14. package/src/openclaw/plugin/claworld-channel-plugin.js +118 -623
  15. package/src/openclaw/plugin/config-schema.js +3 -15
  16. package/src/openclaw/plugin/managed-config.js +98 -47
  17. package/src/openclaw/plugin/onboarding.js +7 -3
  18. package/src/openclaw/plugin/register.js +37 -336
  19. package/src/openclaw/plugin/relay-client.js +111 -101
  20. package/src/openclaw/protocol/relay-event-protocol.js +34 -22
  21. package/src/openclaw/runtime/canonical-result-builder.js +15 -5
  22. package/src/openclaw/runtime/demo-session-bootstrap.js +0 -4
  23. package/src/openclaw/runtime/feedback-helper.js +3 -2
  24. package/src/openclaw/runtime/inbound-session-router.js +28 -20
  25. package/src/openclaw/runtime/outbound-session-bridge.js +21 -9
  26. package/src/openclaw/runtime/product-shell-helper.js +43 -636
  27. package/src/openclaw/runtime/runtime-path.js +2 -2
  28. package/src/openclaw/runtime/system-message-orchestrator.js +1 -1
  29. package/src/openclaw/runtime/tool-contracts.js +33 -258
  30. package/src/openclaw/runtime/world-moderation-helper.js +11 -65
  31. package/src/product-shell/catalog/default-world-catalog.js +9 -27
  32. package/src/product-shell/contracts/candidate-feed.js +26 -1
  33. package/src/product-shell/contracts/chat-request-approval-policy.js +4 -4
  34. package/src/product-shell/contracts/world-manifest.js +115 -160
  35. package/src/product-shell/contracts/world-orchestration.js +47 -322
  36. package/src/product-shell/feedback/feedback-routes.js +4 -3
  37. package/src/product-shell/feedback/feedback-service.js +11 -8
  38. package/src/product-shell/index.js +5 -6
  39. package/src/product-shell/membership/membership-service.js +125 -147
  40. package/src/product-shell/onboarding/onboarding-service.js +2 -2
  41. package/src/product-shell/orchestration/world-conversation-orchestrator.js +30 -0
  42. package/src/product-shell/orchestration/world-conversation-text.js +231 -0
  43. package/src/product-shell/results/result-service.js +9 -3
  44. package/src/product-shell/search/search-service.js +28 -1
  45. package/src/product-shell/social/chat-request-routes.js +0 -1
  46. package/src/product-shell/social/chat-request-service.js +1 -102
  47. package/src/product-shell/worlds/world-admin-service.js +85 -276
  48. package/src/product-shell/worlds/world-authorization.js +3 -5
  49. package/src/product-shell/worlds/world-routes.js +8 -38
  50. package/src/product-shell/worlds/world-service.js +3 -3
  51. package/src/product-shell/worlds/world-text.js +77 -0
  52. package/src/lib/runtime-guidance.js +0 -457
  53. package/src/openclaw/runtime/world-session-startup.js +0 -1
  54. package/src/product-shell/orchestration/session-orchestrator.js +0 -38
@@ -1,6 +1,6 @@
1
- const DEFAULT_MODE = 'manual_review';
1
+ const DEFAULT_MODE = 'open';
2
2
  const SUPPORTED_MODES = Object.freeze([
3
- DEFAULT_MODE,
3
+ 'manual_review',
4
4
  'world_only',
5
5
  'trusted_only',
6
6
  'trusted_or_world',
@@ -45,7 +45,7 @@ export function normalizeChatRequestApprovalMode(value, fallback = DEFAULT_MODE)
45
45
  case 'manual':
46
46
  case 'manual_review':
47
47
  case 'review':
48
- return DEFAULT_MODE;
48
+ return 'manual_review';
49
49
  case 'world':
50
50
  case 'world_only':
51
51
  return 'world_only';
@@ -88,7 +88,7 @@ export function normalizeChatRequestApprovalPolicy(
88
88
  : normalizedLegacyAutoAccept === true
89
89
  ? 'open'
90
90
  : normalizedLegacyAutoAccept === false
91
- ? DEFAULT_MODE
91
+ ? 'manual_review'
92
92
  : normalizeChatRequestApprovalMode(fallbackMode, DEFAULT_MODE);
93
93
 
94
94
  return {
@@ -1,5 +1,6 @@
1
1
  import { projectCandidateFeedModel } from './candidate-feed.js';
2
2
  import { buildWorldSessionStartupText } from './world-orchestration.js';
3
+ import { buildWorldContextText } from '../worlds/world-text.js';
3
4
 
4
5
  function normalizeText(value, fallback = null) {
5
6
  if (value == null) return fallback;
@@ -96,17 +97,21 @@ function normalizeExampleSignals(exampleSignals = {}) {
96
97
  }
97
98
 
98
99
  function normalizeJoinSchema(joinSchema = {}) {
99
- const requiredFields = Array.isArray(joinSchema.requiredFields)
100
- ? joinSchema.requiredFields.map((field, index) => normalizeField(field, index, { required: true }))
101
- : [];
102
- const optionalFields = Array.isArray(joinSchema.optionalFields)
103
- ? joinSchema.optionalFields.map((field, index) => normalizeField(field, index, { required: false }))
104
- : [];
105
-
106
100
  return {
107
- requiredFields,
108
- optionalFields,
109
- hints: normalizeStringList(joinSchema.hints),
101
+ requiredFields: [
102
+ {
103
+ fieldId: 'participantContextText',
104
+ label: 'Entry Profile',
105
+ type: 'string',
106
+ source: 'membership',
107
+ required: true,
108
+ description: 'Free-form participant profile/context text used for world join, search, and candidate review.',
109
+ examples: [],
110
+ constraints: {},
111
+ },
112
+ ],
113
+ optionalFields: [],
114
+ hints: [],
110
115
  };
111
116
  }
112
117
 
@@ -157,12 +162,25 @@ function normalizeSearchSchema(searchSchema = {}, joinSchema = {}) {
157
162
  };
158
163
  }
159
164
 
165
+ function resolveConversationTemplateInput(manifest = {}) {
166
+ if (manifest.conversationTemplate && typeof manifest.conversationTemplate === 'object' && !Array.isArray(manifest.conversationTemplate)) {
167
+ return manifest.conversationTemplate;
168
+ }
169
+ return {};
170
+ }
171
+
160
172
  export function normalizeWorldManifest(manifest = {}, index = 0) {
161
173
  const worldId = normalizeText(manifest.worldId || manifest.id, `world_${index + 1}`);
162
174
  const joinSchema = normalizeJoinSchema(manifest.joinSchema);
163
175
  const searchSchema = normalizeSearchSchema(manifest.searchSchema, joinSchema);
164
- const defaultInteractionRules = normalizeText(manifest.sessionTemplate?.worldRules?.openingText, null);
165
- const defaultProhibitedRules = normalizeText(manifest.sessionTemplate?.raiseHandPolicy?.summary, null);
176
+ const conversationTemplate = resolveConversationTemplateInput(manifest);
177
+ const defaultInteractionRules = normalizeText(conversationTemplate?.worldRules?.openingText, null);
178
+ const normalizedInteractionRules = normalizeText(manifest.interactionRules, defaultInteractionRules);
179
+ const normalizedProhibitedRules = normalizeText(manifest.prohibitedRules, null);
180
+ const normalizedRatingRules = normalizeText(
181
+ manifest.ratingRules,
182
+ 'After the interaction ends, each agent should rate the other participant from 1 to 10 based on fit, clarity, and rule compliance.',
183
+ );
166
184
 
167
185
  return {
168
186
  worldId,
@@ -173,12 +191,21 @@ export function normalizeWorldManifest(manifest = {}, index = 0) {
173
191
  category: normalizeText(manifest.category, 'general'),
174
192
  lifecycle: normalizeText(manifest.lifecycle, 'scaffold'),
175
193
  tags: normalizeStringList(manifest.tags),
176
- interactionRules: normalizeText(manifest.interactionRules, defaultInteractionRules),
177
- prohibitedRules: normalizeText(manifest.prohibitedRules, defaultProhibitedRules),
178
- ratingRules: normalizeText(
179
- manifest.ratingRules,
180
- 'After the interaction ends, each agent should rate the other participant from 1 to 10 based on fit, clarity, and rule compliance.',
181
- ),
194
+ interactionRules: normalizedInteractionRules,
195
+ prohibitedRules: normalizedProhibitedRules,
196
+ ratingRules: normalizedRatingRules,
197
+ worldContextText: buildWorldContextText({
198
+ worldId,
199
+ displayName: normalizeText(manifest.displayName, worldId),
200
+ summary: normalizeText(manifest.summary, null),
201
+ worldContextText: normalizeText(
202
+ manifest.worldContextText,
203
+ normalizeText(manifest.runtimeWorldContext?.text, null),
204
+ ),
205
+ interactionRules: normalizedInteractionRules,
206
+ prohibitedRules: normalizedProhibitedRules,
207
+ ratingRules: normalizedRatingRules,
208
+ }),
182
209
  creatorAgentId: normalizeText(manifest.creatorAgentId, null),
183
210
  adminAgentIds: normalizeStringList(manifest.adminAgentIds),
184
211
  eligibility: normalizeWorldEligibility(manifest.eligibility, 'active'),
@@ -208,25 +235,15 @@ export function normalizeWorldManifest(manifest = {}, index = 0) {
208
235
  strategySummary: normalizeText(manifest.matching?.strategySummary, null),
209
236
  candidateSources: normalizeCandidateSources(manifest.matching?.candidateSources),
210
237
  },
211
- sessionTemplate: {
212
- mode: normalizeText(manifest.sessionTemplate?.mode, 'a2a'),
213
- maxTurns: Number.isFinite(Number(manifest.sessionTemplate?.maxTurns))
214
- ? Math.max(1, Number(manifest.sessionTemplate.maxTurns))
215
- : 6,
216
- turnTimeoutMs: Number.isFinite(Number(manifest.sessionTemplate?.turnTimeoutMs))
217
- ? Math.max(1000, Number(manifest.sessionTemplate.turnTimeoutMs))
218
- : 60_000,
219
- raiseHandPolicy: {
220
- mode: normalizeText(manifest.sessionTemplate?.raiseHandPolicy?.mode, 'dual_raise_hand'),
221
- summary: normalizeText(manifest.sessionTemplate?.raiseHandPolicy?.summary, null),
222
- },
238
+ conversationTemplate: {
239
+ mode: normalizeText(conversationTemplate?.mode, 'a2a'),
223
240
  worldRules: {
224
- openingText: normalizeText(manifest.sessionTemplate?.worldRules?.openingText, null),
225
- turnMessageRules: Array.isArray(manifest.sessionTemplate?.worldRules?.turnMessageRules)
226
- ? manifest.sessionTemplate.worldRules.turnMessageRules
241
+ openingText: normalizeText(conversationTemplate?.worldRules?.openingText, null),
242
+ turnMessageRules: Array.isArray(conversationTemplate?.worldRules?.turnMessageRules)
243
+ ? conversationTemplate.worldRules.turnMessageRules
227
244
  : [],
228
- convergence: manifest.sessionTemplate?.worldRules?.convergence || {},
229
- stateChangeMessages: manifest.sessionTemplate?.worldRules?.stateChangeMessages || {},
245
+ convergence: conversationTemplate?.worldRules?.convergence || {},
246
+ stateChangeMessages: conversationTemplate?.worldRules?.stateChangeMessages || {},
230
247
  },
231
248
  },
232
249
  resultContract: {
@@ -243,40 +260,26 @@ export function normalizeWorldManifest(manifest = {}, index = 0) {
243
260
  }
244
261
 
245
262
  export function projectWorldCard(world) {
246
- const agentSummary = {
247
- displayName: world.displayName,
248
- summary: world.summary,
249
- category: world.category,
250
- requiredFieldCount: world.joinSchema.requiredFields.length,
251
- matchingMode: world.matching.mode,
252
- sessionMode: world.sessionTemplate.mode,
253
- };
254
-
255
263
  return {
256
264
  worldId: world.worldId,
257
265
  slug: world.slug,
258
- displayName: agentSummary.displayName,
259
- summary: agentSummary.summary,
260
- category: agentSummary.category,
261
- lifecycle: world.lifecycle,
262
- tags: world.tags,
263
- requiredFieldCount: agentSummary.requiredFieldCount,
264
- roleCount: world.roles.length,
265
- matchingMode: agentSummary.matchingMode,
266
- sessionMode: agentSummary.sessionMode,
266
+ displayName: world.displayName,
267
+ worldContextText: world.worldContextText,
267
268
  createdAt: world.createdAt || null,
268
269
  updatedAt: world.updatedAt || null,
269
- status: world.meta.status,
270
- agentSummary,
270
+ status: world.status || world.meta.status,
271
+ enabled: world.enabled === true,
271
272
  };
272
273
  }
273
274
 
274
275
  export function projectJoinPlan(world) {
275
276
  return {
276
277
  worldId: world.worldId,
277
- requiredFields: world.joinSchema.requiredFields,
278
- optionalFields: world.joinSchema.optionalFields,
279
- hints: world.joinSchema.hints,
278
+ participantContextField: {
279
+ fieldId: 'participantContextText',
280
+ label: 'Entry Profile',
281
+ description: 'A short text describing who you are in this world and what context you bring into it.',
282
+ },
280
283
  nextAction: 'call_join_world',
281
284
  };
282
285
  }
@@ -314,140 +317,92 @@ export function projectSearchModel(world) {
314
317
 
315
318
  export function projectWorldDetail(world) {
316
319
  const joinPlan = projectJoinPlan(world);
317
- const requiredFieldGuide = projectFieldGuide(world.joinSchema.requiredFields, { required: true });
318
- const optionalFieldGuide = projectFieldGuide(world.joinSchema.optionalFields, { required: false });
319
- const allFieldGuide = [...requiredFieldGuide, ...optionalFieldGuide];
320
- const candidateFeedOverview = projectCandidateFeedModel(world);
321
- const searchSchema = projectSearchModel(world);
322
- const runtimeStartupContext = {
323
- worldId: world.worldId,
324
- status: 'ready',
325
- source: 'product_shell_session_startup',
326
- text: buildWorldSessionStartupText({
320
+ const worldContextText = normalizeText(
321
+ world.worldContextText,
322
+ buildWorldSessionStartupText({
327
323
  worldId: world.worldId,
328
324
  displayName: world.displayName,
329
325
  summary: world.summary,
330
326
  interactionRules: world.interactionRules,
331
327
  prohibitedRules: world.prohibitedRules,
332
328
  ratingRules: world.ratingRules,
333
- sessionMode: world.sessionTemplate.mode,
334
- sessionOverview: {
329
+ conversationMode: world.conversationTemplate.mode,
330
+ conversationOverview: {
335
331
  worldId: world.worldId,
336
- mode: world.sessionTemplate.mode,
337
- maxTurns: world.sessionTemplate.maxTurns,
338
- turnTimeoutMs: world.sessionTemplate.turnTimeoutMs,
339
- raiseHandPolicy: world.sessionTemplate.raiseHandPolicy,
340
- openingText: world.sessionTemplate.worldRules.openingText,
341
- convergence: world.sessionTemplate.worldRules.convergence,
332
+ mode: world.conversationTemplate.mode,
333
+ openingText: world.conversationTemplate.worldRules.openingText,
334
+ convergence: world.conversationTemplate.worldRules.convergence,
342
335
  },
343
336
  }),
344
- };
337
+ );
345
338
 
346
339
  return {
347
- world: world,
348
- agentSummary: {
349
- displayName: world.displayName,
350
- summary: world.summary,
351
- category: world.category,
352
- requiredFieldCount: world.joinSchema.requiredFields.length,
353
- optionalFieldCount: world.joinSchema.optionalFields.length,
354
- matchingMode: world.matching.mode,
355
- sessionMode: world.sessionTemplate.mode,
356
- },
357
- joinSchema: {
358
- worldId: world.worldId,
359
- requiredFields: world.joinSchema.requiredFields,
360
- optionalFields: world.joinSchema.optionalFields,
361
- requiredFieldIds: requiredFieldGuide.map((field) => field.fieldId),
362
- optionalFieldIds: optionalFieldGuide.map((field) => field.fieldId),
363
- requiredFieldCount: requiredFieldGuide.length,
364
- optionalFieldCount: optionalFieldGuide.length,
365
- hints: world.joinSchema.hints,
366
- nextAction: joinPlan.nextAction,
367
- },
368
- fieldGuide: {
369
- required: requiredFieldGuide,
370
- optional: optionalFieldGuide,
371
- allFields: allFieldGuide,
372
- },
373
- sessionOverview: {
340
+ worldId: world.worldId,
341
+ world: {
374
342
  worldId: world.worldId,
375
- mode: world.sessionTemplate.mode,
376
- maxTurns: world.sessionTemplate.maxTurns,
377
- turnTimeoutMs: world.sessionTemplate.turnTimeoutMs,
378
- raiseHandPolicy: world.sessionTemplate.raiseHandPolicy,
379
- openingText: world.sessionTemplate.worldRules.openingText,
380
- convergence: world.sessionTemplate.worldRules.convergence,
381
- turnMessageRules: world.sessionTemplate.worldRules.turnMessageRules,
382
- expectationSummary:
383
- `Expect a ${world.sessionTemplate.mode} session with up to ${world.sessionTemplate.maxTurns} turns and ` +
384
- `a ${world.sessionTemplate.turnTimeoutMs}ms turn timeout before the world asks both agents to converge.`,
385
- status: 'scaffold_ready',
343
+ displayName: world.displayName,
344
+ worldContextText,
386
345
  },
387
- matchingOverview: {
388
- worldId: world.worldId,
389
- mode: world.matching.mode,
390
- cadence: world.matching.cadence,
391
- strategySummary: world.matching.strategySummary,
392
- candidateSources: world.matching.candidateSources,
393
- inputFields: requiredFieldGuide.map((field) => field.fieldId),
394
- optionalContextFields: optionalFieldGuide.map((field) => field.fieldId),
395
- searchMode: searchSchema.mode,
396
- deliveryMode: candidateFeedOverview.deliveryMode,
397
- status: 'scaffold_ready',
346
+ management: {
347
+ ownerAgentId: world.creatorAgentId || null,
348
+ enabled: world.enabled === true,
349
+ status: world.status || world.meta.status,
350
+ createdAt: world.createdAt || null,
351
+ updatedAt: world.updatedAt || null,
352
+ memberCount: world.metrics?.memberCount || null,
353
+ totalConversationCount: Number.isFinite(Number(world.metrics?.totalConversationCount))
354
+ ? Math.max(0, Math.trunc(Number(world.metrics.totalConversationCount)))
355
+ : 0,
398
356
  },
399
- searchSchema,
400
- candidateFeedOverview,
357
+ participantContextField: joinPlan.participantContextField,
401
358
  joinPlan,
402
- runtimeStartupContext,
359
+ worldContextText,
403
360
  };
404
361
  }
405
362
 
406
- export function projectSessionStartupContext(world) {
407
- const runtimeStartupContext = {
363
+ export function projectConversationWorldContext(world) {
364
+ const runtimeWorldContext = {
408
365
  worldId: world.worldId,
409
366
  status: 'ready',
410
- source: 'product_shell_session_startup',
411
- text: buildWorldSessionStartupText({
412
- worldId: world.worldId,
413
- displayName: world.displayName,
414
- summary: world.summary,
415
- interactionRules: world.interactionRules,
416
- prohibitedRules: world.prohibitedRules,
417
- ratingRules: world.ratingRules,
418
- sessionMode: world.sessionTemplate.mode,
419
- sessionOverview: {
367
+ source: 'product_shell_conversation_world_context',
368
+ text: normalizeText(
369
+ world.worldContextText,
370
+ buildWorldSessionStartupText({
420
371
  worldId: world.worldId,
421
- mode: world.sessionTemplate.mode,
422
- maxTurns: world.sessionTemplate.maxTurns,
423
- turnTimeoutMs: world.sessionTemplate.turnTimeoutMs,
424
- raiseHandPolicy: world.sessionTemplate.raiseHandPolicy,
425
- openingText: world.sessionTemplate.worldRules.openingText,
426
- convergence: world.sessionTemplate.worldRules.convergence,
427
- },
428
- }),
372
+ displayName: world.displayName,
373
+ summary: world.summary,
374
+ interactionRules: world.interactionRules,
375
+ prohibitedRules: world.prohibitedRules,
376
+ ratingRules: world.ratingRules,
377
+ conversationMode: world.conversationTemplate.mode,
378
+ conversationOverview: {
379
+ worldId: world.worldId,
380
+ mode: world.conversationTemplate.mode,
381
+ openingText: world.conversationTemplate.worldRules.openingText,
382
+ convergence: world.conversationTemplate.worldRules.convergence,
383
+ },
384
+ }),
385
+ ),
429
386
  };
430
387
 
431
388
  return {
432
389
  worldId: world.worldId,
433
390
  displayName: world.displayName,
434
391
  summary: world.summary,
392
+ worldContextText: runtimeWorldContext.text,
435
393
  interactionRules: world.interactionRules,
436
394
  prohibitedRules: world.prohibitedRules,
437
395
  ratingRules: world.ratingRules,
438
- sessionMode: world.sessionTemplate.mode,
439
- sessionOverview: {
396
+ conversationMode: world.conversationTemplate.mode,
397
+ conversationOverview: {
440
398
  worldId: world.worldId,
441
- mode: world.sessionTemplate.mode,
442
- maxTurns: world.sessionTemplate.maxTurns,
443
- turnTimeoutMs: world.sessionTemplate.turnTimeoutMs,
444
- raiseHandPolicy: world.sessionTemplate.raiseHandPolicy,
445
- openingText: world.sessionTemplate.worldRules.openingText,
446
- convergence: world.sessionTemplate.worldRules.convergence,
447
- turnMessageRules: world.sessionTemplate.worldRules.turnMessageRules,
399
+ mode: world.conversationTemplate.mode,
400
+ openingText: world.conversationTemplate.worldRules.openingText,
401
+ convergence: world.conversationTemplate.worldRules.convergence,
402
+ turnMessageRules: world.conversationTemplate.worldRules.turnMessageRules,
448
403
  },
449
404
  status: 'ready',
450
- source: 'product_shell_session_startup',
451
- runtimeStartupContext,
405
+ source: 'product_shell_conversation_world_context',
406
+ runtimeWorldContext,
452
407
  };
453
408
  }