@xfxstudio/claworld 0.2.6 → 0.2.8

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.
@@ -77,15 +77,6 @@ function normalizeField(field = {}, index = 0, { required = false } = {}) {
77
77
  };
78
78
  }
79
79
 
80
- function normalizeExampleSignals(exampleSignals = {}) {
81
- const normalizeGroup = (key) => (Array.isArray(exampleSignals[key]) ? exampleSignals[key] : []);
82
- return {
83
- intentSignals: normalizeGroup('intentSignals'),
84
- conversationSignals: normalizeGroup('conversationSignals'),
85
- agentSignals: normalizeGroup('agentSignals'),
86
- };
87
- }
88
-
89
80
  function normalizeJoinSchema(joinSchema = {}) {
90
81
  return {
91
82
  requiredFields: [
@@ -167,10 +158,6 @@ export function normalizeWorldManifest(manifest = {}, index = 0) {
167
158
  const defaultInteractionRules = normalizeText(conversationTemplate?.worldRules?.openingText, null);
168
159
  const normalizedInteractionRules = normalizeText(manifest.interactionRules, defaultInteractionRules);
169
160
  const normalizedProhibitedRules = normalizeText(manifest.prohibitedRules, null);
170
- const normalizedRatingRules = normalizeText(
171
- manifest.ratingRules,
172
- 'After the interaction ends, each agent should rate the other participant from 1 to 10 based on fit, clarity, and rule compliance.',
173
- );
174
161
 
175
162
  return {
176
163
  worldId,
@@ -183,7 +170,6 @@ export function normalizeWorldManifest(manifest = {}, index = 0) {
183
170
  tags: normalizeStringList(manifest.tags),
184
171
  interactionRules: normalizedInteractionRules,
185
172
  prohibitedRules: normalizedProhibitedRules,
186
- ratingRules: normalizedRatingRules,
187
173
  worldContextText: buildWorldContextText({
188
174
  worldId,
189
175
  displayName: normalizeText(manifest.displayName, worldId),
@@ -194,7 +180,6 @@ export function normalizeWorldManifest(manifest = {}, index = 0) {
194
180
  ),
195
181
  interactionRules: normalizedInteractionRules,
196
182
  prohibitedRules: normalizedProhibitedRules,
197
- ratingRules: normalizedRatingRules,
198
183
  }),
199
184
  creatorAgentId: normalizeText(manifest.creatorAgentId, null),
200
185
  eligibility: normalizeWorldEligibility(manifest.eligibility, 'active'),
@@ -232,12 +217,6 @@ export function normalizeWorldManifest(manifest = {}, index = 0) {
232
217
  stateChangeMessages: conversationTemplate?.worldRules?.stateChangeMessages || {},
233
218
  },
234
219
  },
235
- resultContract: {
236
- schemaId: normalizeText(manifest.resultContract?.schemaId, `${worldId}.result.v1`),
237
- outputs: normalizeStringList(manifest.resultContract?.outputs),
238
- successCriteria: normalizeStringList(manifest.resultContract?.successCriteria),
239
- exampleSignals: normalizeExampleSignals(manifest.resultContract?.exampleSignals),
240
- },
241
220
  meta: {
242
221
  status: normalizeText(manifest.meta?.status, 'scaffold_ready'),
243
222
  persistence: normalizeText(manifest.meta?.persistence, 'in_memory_catalog'),
@@ -311,7 +290,6 @@ export function projectWorldDetail(world) {
311
290
  summary: world.summary,
312
291
  interactionRules: world.interactionRules,
313
292
  prohibitedRules: world.prohibitedRules,
314
- ratingRules: world.ratingRules,
315
293
  conversationMode: world.conversationTemplate.mode,
316
294
  conversationOverview: {
317
295
  worldId: world.worldId,
@@ -359,7 +337,6 @@ export function projectConversationWorldContext(world) {
359
337
  summary: world.summary,
360
338
  interactionRules: world.interactionRules,
361
339
  prohibitedRules: world.prohibitedRules,
362
- ratingRules: world.ratingRules,
363
340
  conversationMode: world.conversationTemplate.mode,
364
341
  conversationOverview: {
365
342
  worldId: world.worldId,
@@ -378,7 +355,6 @@ export function projectConversationWorldContext(world) {
378
355
  worldContextText: runtimeWorldContext.text,
379
356
  interactionRules: world.interactionRules,
380
357
  prohibitedRules: world.prohibitedRules,
381
- ratingRules: world.ratingRules,
382
358
  conversationMode: world.conversationTemplate.mode,
383
359
  conversationOverview: {
384
360
  worldId: world.worldId,
@@ -173,7 +173,6 @@ function normalizeWorldDetail(payload = {}) {
173
173
  conversationMode: normalizeText(payload.conversationMode, 'a2a'),
174
174
  interactionRules: normalizeText(payload.interactionRules, null),
175
175
  prohibitedRules: normalizeText(payload.prohibitedRules, null),
176
- ratingRules: normalizeText(payload.ratingRules, null),
177
176
  eligibility: normalizeText(payload.eligibility, 'active'),
178
177
  broadcast: normalizeBroadcastConfig(payload.broadcast),
179
178
  requiredFields,
@@ -235,7 +234,6 @@ function normalizeWorldDetail(payload = {}) {
235
234
  ),
236
235
  interactionRules: normalizeText(payload.interactionRules || world.interactionRules, null),
237
236
  prohibitedRules: normalizeText(payload.prohibitedRules || world.prohibitedRules, null),
238
- ratingRules: normalizeText(payload.ratingRules || world.ratingRules, null),
239
237
  eligibility: normalizeText(payload.eligibility || world.eligibility, 'active'),
240
238
  broadcast: normalizeBroadcastConfig(payload.broadcast || world.broadcast),
241
239
  requiredFields,
@@ -422,7 +420,6 @@ export function buildWorldSessionStartupText(detail = {}) {
422
420
  const convergenceText = normalizeText(conversationOverview.convergence?.text, null);
423
421
  const interactionRules = normalizeText(normalizedDetail.interactionRules, null);
424
422
  const prohibitedRules = normalizeText(normalizedDetail.prohibitedRules, null);
425
- const ratingRules = normalizeText(normalizedDetail.ratingRules, null);
426
423
 
427
424
  const lines = [
428
425
  'Internal Claworld world context for this conversation.',
@@ -434,7 +431,6 @@ export function buildWorldSessionStartupText(detail = {}) {
434
431
  openingText ? `Opening focus: ${openingText}` : null,
435
432
  interactionRules ? `Interaction rules: ${interactionRules}` : null,
436
433
  prohibitedRules ? `Prohibited rules: ${prohibitedRules}` : null,
437
- ratingRules ? `Rating rules: ${ratingRules}` : null,
438
434
  convergenceText ? `Convergence rule: ${convergenceText}` : null,
439
435
  'Apply these world rules symmetrically when responding in this conversation.',
440
436
  ].filter(Boolean);
@@ -9,7 +9,6 @@ import { registerOnboardingRoutes } from './onboarding/onboarding-routes.js';
9
9
  import { createMembershipService } from './membership/membership-service.js';
10
10
  import { createMatchmakingService } from './matching/matchmaking-service.js';
11
11
  import { createWorldSearchService } from './search/search-service.js';
12
- import { createResultService } from './results/result-service.js';
13
12
  import { createWorldConversationOrchestrator } from './orchestration/world-conversation-orchestrator.js';
14
13
  import { createSocialService } from './social/social-service.js';
15
14
  import { registerSocialRoutes } from './social/social-routes.js';
@@ -50,7 +49,6 @@ export function createClaworldProductShell({
50
49
  chatRequestService,
51
50
  store,
52
51
  });
53
- const resultService = createResultService();
54
52
  const friendService = createFriendService({ store, policy: relay?.policy });
55
53
  const socialLookupService = createSocialService({ worldService, store });
56
54
  const feedbackService = createFeedbackService({ store });
@@ -62,7 +60,6 @@ export function createClaworldProductShell({
62
60
  };
63
61
  const worldConversationOrchestrator = createWorldConversationOrchestrator({
64
62
  worldService,
65
- resultService,
66
63
  });
67
64
 
68
65
  const productShell = {
@@ -78,7 +75,6 @@ export function createClaworldProductShell({
78
75
  chatRequests: chatRequestService,
79
76
  moderation: worldAdminService,
80
77
  feedback: feedbackService,
81
- results: resultService,
82
78
  orchestration: worldConversationOrchestrator,
83
79
  },
84
80
  registerRoutes(app) {
@@ -115,7 +111,6 @@ export function createClaworldProductShell({
115
111
  'moderation',
116
112
  'feedback',
117
113
  'orchestration',
118
- 'results',
119
114
  ],
120
115
  routes: [
121
116
  'GET /v1/meta/product-shell',
@@ -2,7 +2,6 @@ import { createSystemMessageOrchestrator } from './world-conversation-text.js';
2
2
 
3
3
  export function createWorldConversationOrchestrator({
4
4
  worldService,
5
- resultService,
6
5
  systemMessages = createSystemMessageOrchestrator(),
7
6
  } = {}) {
8
7
  return {
@@ -22,7 +21,6 @@ export function createWorldConversationOrchestrator({
22
21
  },
23
22
  openingPlan,
24
23
  convergencePlan,
25
- resultPreview: resultService.previewConversation({ world, conversationKey }),
26
24
  status: 'preview_ready',
27
25
  };
28
26
  },
@@ -86,7 +86,6 @@ export function buildWorldConversationContextEvent(detail = {}) {
86
86
  const convergenceText = normalizeText(conversationOverview.convergence?.text, null);
87
87
  const interactionRules = normalizeText(detail.interactionRules, null);
88
88
  const prohibitedRules = normalizeText(detail.prohibitedRules, null);
89
- const ratingRules = normalizeText(detail.ratingRules, null);
90
89
 
91
90
  const lines = [
92
91
  'Internal Claworld world context for this conversation.',
@@ -98,7 +97,6 @@ export function buildWorldConversationContextEvent(detail = {}) {
98
97
  openingText ? `Opening focus: ${openingText}` : null,
99
98
  interactionRules ? `Interaction rules: ${interactionRules}` : null,
100
99
  prohibitedRules ? `Prohibited rules: ${prohibitedRules}` : null,
101
- ratingRules ? `Rating rules: ${ratingRules}` : null,
102
100
  convergenceText ? `Convergence rule: ${convergenceText}` : null,
103
101
  'Apply these world rules symmetrically when responding in this conversation.',
104
102
  ].filter(Boolean);
@@ -198,6 +198,7 @@ function resolveAcceptNextAction(kickoff) {
198
198
  const kickoffStatus = kickoff?.status || 'skipped';
199
199
  if (kickoffStatus === 'established') return 'runtime_owns_live_conversation';
200
200
  if (kickoffStatus === 'sent') return 'wait_for_sender_opener_delivery';
201
+ if (kickoffStatus === 'kept_silent') return 'sender_kept_silent';
201
202
  if (kickoffStatus === 'failed') return 'backend_kickoff_failed';
202
203
  return 'chat_request_accepted_without_opening_message';
203
204
  }
@@ -12,6 +12,36 @@ function normalizeBoolean(value, fallback = false) {
12
12
  return fallback;
13
13
  }
14
14
 
15
+ const OWNER_WORLD_STATUSES = new Set(['draft', 'enabled', 'paused', 'closed', 'disabled']);
16
+
17
+ function normalizeOwnerWorldStatus(value, fallback = null) {
18
+ const normalized = normalizeText(value, fallback);
19
+ return OWNER_WORLD_STATUSES.has(normalized) ? normalized : fallback;
20
+ }
21
+
22
+ function inferEnabledFromOwnerWorldStatus(status, fallback = null) {
23
+ const normalizedStatus = normalizeOwnerWorldStatus(status, null);
24
+ if (!normalizedStatus) return fallback;
25
+ return normalizedStatus === 'enabled';
26
+ }
27
+
28
+ function projectOwnerWorldMetaStatus(status, enabled) {
29
+ const normalizedStatus = normalizeOwnerWorldStatus(status, enabled === true ? 'enabled' : 'draft');
30
+ switch (normalizedStatus) {
31
+ case 'enabled':
32
+ return 'creator_enabled';
33
+ case 'paused':
34
+ return 'creator_paused';
35
+ case 'closed':
36
+ return 'creator_closed';
37
+ case 'disabled':
38
+ return 'creator_disabled';
39
+ case 'draft':
40
+ default:
41
+ return 'creator_draft';
42
+ }
43
+ }
44
+
15
45
  function summarizeWorldContextText(worldContextText, fallback = null) {
16
46
  const normalized = normalizeText(worldContextText, null);
17
47
  if (!normalized) return fallback;
@@ -144,19 +174,6 @@ function buildConversationTemplate(interactionRules, prohibitedRules, { existing
144
174
  };
145
175
  }
146
176
 
147
- function buildResultContract(worldId, ratingRules) {
148
- return {
149
- schemaId: `${worldId}.result.v1`,
150
- outputs: ['rating', 'recommendation', 'notes'],
151
- successCriteria: [ratingRules || 'Each side gives an explicit 1 to 10 rating.'],
152
- exampleSignals: {
153
- intentSignals: [],
154
- conversationSignals: [],
155
- agentSignals: [],
156
- },
157
- };
158
- }
159
-
160
177
  function buildWorldRecord({
161
178
  worldId,
162
179
  creatorAgentId,
@@ -167,7 +184,7 @@ function buildWorldRecord({
167
184
  status = null,
168
185
  existingMetrics = null,
169
186
  } = {}) {
170
- const resolvedStatus = status || (enabled ? 'enabled' : 'draft');
187
+ const resolvedStatus = normalizeOwnerWorldStatus(status, enabled ? 'enabled' : 'draft');
171
188
  const participantContextField = buildDefaultEntryProfileField();
172
189
  const resolvedWorldContextText = buildWorldContextText({
173
190
  worldId,
@@ -176,7 +193,6 @@ function buildWorldRecord({
176
193
  worldContextText,
177
194
  interactionRules: null,
178
195
  prohibitedRules: null,
179
- ratingRules: null,
180
196
  });
181
197
 
182
198
  return {
@@ -190,7 +206,6 @@ function buildWorldRecord({
190
206
  tags: ['ugc', 'creator-managed'],
191
207
  interactionRules: null,
192
208
  prohibitedRules: null,
193
- ratingRules: null,
194
209
  worldContextText: resolvedWorldContextText,
195
210
  joinSchema: {
196
211
  requiredFields: [participantContextField],
@@ -200,9 +215,8 @@ function buildWorldRecord({
200
215
  searchSchema: buildSearchSchema(),
201
216
  matching: buildMatchingStrategy(),
202
217
  conversationTemplate: buildConversationTemplate(null, null),
203
- resultContract: buildResultContract(worldId, null),
204
218
  meta: {
205
- status: resolvedStatus === 'enabled' ? 'creator_enabled' : 'creator_draft',
219
+ status: projectOwnerWorldMetaStatus(resolvedStatus, enabled),
206
220
  persistence: 'store',
207
221
  },
208
222
  creatorAgentId,
@@ -330,6 +344,7 @@ export function createWorldAdminService({ worldService, worldAuthorizationServic
330
344
  displayName,
331
345
  worldContextText,
332
346
  enabled = false,
347
+ status = null,
333
348
  } = {}) {
334
349
  const storeBacked = assertStore();
335
350
  const resolvedOwnerAgentId = assertActorAgent(ownerAgentId || creatorAgentId);
@@ -344,12 +359,9 @@ export function createWorldAdminService({ worldService, worldAuthorizationServic
344
359
  creatorAgentId: resolvedOwnerAgentId,
345
360
  displayName: resolvedDisplayName,
346
361
  summary: summarizeWorldContextText(resolvedWorldContextText, resolvedDisplayName),
347
- description: resolvedWorldContextText,
348
- interactionRules: null,
349
- prohibitedRules: null,
350
- ratingRules: null,
351
362
  worldContextText: resolvedWorldContextText,
352
363
  enabled: normalizeBoolean(enabled, false),
364
+ status: normalizeOwnerWorldStatus(status, normalizeBoolean(enabled, false) ? 'enabled' : 'draft'),
353
365
  });
354
366
 
355
367
  const created = await storeBacked.createWorldConfig(worldRecord);
@@ -387,10 +399,14 @@ export function createWorldAdminService({ worldService, worldAuthorizationServic
387
399
  worldRole: authorization.worldRole,
388
400
  });
389
401
  },
390
- async manageWorld({ actorAgentId, creatorAgentId, worldId, changes = null, enabled = null } = {}) {
402
+ async manageWorld({ actorAgentId, creatorAgentId, worldId, changes = null, enabled = null, status = null } = {}) {
391
403
  const storeBacked = assertStore();
392
404
  const resolvedActorAgentId = assertActorAgent(actorAgentId || creatorAgentId);
393
405
  const hasChanges = changes && typeof changes === 'object' && !Array.isArray(changes);
406
+ const normalizedStatus = normalizeOwnerWorldStatus(status, null);
407
+ const resolvedEnabled = normalizedStatus != null
408
+ ? inferEnabledFromOwnerWorldStatus(normalizedStatus, null)
409
+ : (enabled == null ? null : normalizeBoolean(enabled, false));
394
410
 
395
411
  const authorization = requireWorldOwner({
396
412
  worldId,
@@ -398,7 +414,7 @@ export function createWorldAdminService({ worldService, worldAuthorizationServic
398
414
  });
399
415
 
400
416
  const existingWorld = authorization.world;
401
- if (!hasChanges && enabled == null) {
417
+ if (!hasChanges && resolvedEnabled == null && normalizedStatus == null) {
402
418
  return projectManagedWorld(storeBacked, existingWorld, {
403
419
  worldRole: authorization.worldRole,
404
420
  });
@@ -417,20 +433,24 @@ export function createWorldAdminService({ worldService, worldAuthorizationServic
417
433
  displayName: nextDisplayName,
418
434
  summary: summarizeWorldContextText(nextWorldContextText, nextDisplayName),
419
435
  worldContextText: nextWorldContextText,
420
- enabled: enabled == null ? existingWorld.enabled === true : normalizeBoolean(enabled, false),
421
- status: enabled == null
422
- ? existingWorld.status
423
- : (normalizeBoolean(enabled, false) ? 'enabled' : 'disabled'),
436
+ enabled: resolvedEnabled == null ? existingWorld.enabled === true : resolvedEnabled,
437
+ status: normalizedStatus || (
438
+ resolvedEnabled == null
439
+ ? existingWorld.status
440
+ : (resolvedEnabled ? 'enabled' : 'disabled')
441
+ ),
424
442
  existingMetrics: existingWorld.metrics || null,
425
443
  });
426
- } else if (enabled != null) {
444
+ } else if (resolvedEnabled != null || normalizedStatus != null) {
445
+ const nextEnabled = resolvedEnabled == null ? existingWorld.enabled === true : resolvedEnabled;
446
+ const nextStatus = normalizedStatus || (nextEnabled ? 'enabled' : 'disabled');
427
447
  nextRecord = {
428
448
  ...existingWorld,
429
- enabled: normalizeBoolean(enabled, false),
430
- status: normalizeBoolean(enabled, false) ? 'enabled' : 'disabled',
449
+ enabled: nextEnabled,
450
+ status: nextStatus,
431
451
  meta: {
432
452
  ...(existingWorld.meta || {}),
433
- status: normalizeBoolean(enabled, false) ? 'creator_enabled' : 'creator_disabled',
453
+ status: projectOwnerWorldMetaStatus(nextStatus, nextEnabled),
434
454
  },
435
455
  };
436
456
  }
@@ -25,6 +25,18 @@ function resolveWorldRole({ isOwner = false, isMember = false } = {}) {
25
25
  return null;
26
26
  }
27
27
 
28
+ function resolveEffectiveRoles({ isOwner = false, isMember = false } = {}) {
29
+ const roles = [];
30
+ if (isOwner) {
31
+ roles.push(WORLD_ROLES.OWNER);
32
+ // World owners should retain member-scoped capabilities for worlds they are actively in.
33
+ if (isMember) roles.push(WORLD_ROLES.MEMBER);
34
+ return roles;
35
+ }
36
+ if (isMember) roles.push(WORLD_ROLES.MEMBER);
37
+ return roles;
38
+ }
39
+
28
40
  function resolveActionRequirement(action) {
29
41
  switch (action) {
30
42
  case WORLD_ACTIONS.VIEW_MANAGEMENT:
@@ -72,11 +84,13 @@ export function createWorldAuthorizationService({ worldService, membershipServic
72
84
  const isOwner = normalizedActorAgentId != null && normalizedActorAgentId === world.creatorAgentId;
73
85
  const isMember = membership?.status === 'active';
74
86
  const worldRole = resolveWorldRole({ isOwner, isMember });
87
+ const effectiveRoles = resolveEffectiveRoles({ isOwner, isMember });
75
88
 
76
89
  return {
77
90
  world,
78
91
  actorAgentId: normalizedActorAgentId,
79
92
  worldRole,
93
+ effectiveRoles,
80
94
  managementRole: isOwner ? WORLD_ROLES.OWNER : null,
81
95
  membership,
82
96
  membershipStatus: membership?.status || null,
@@ -100,7 +114,7 @@ export function createWorldAuthorizationService({ worldService, membershipServic
100
114
  includeDisabled,
101
115
  });
102
116
  const requirement = resolveActionRequirement(action);
103
- const allowed = requirement.allowedRoles.includes(actor.worldRole);
117
+ const allowed = actor.effectiveRoles.some((role) => requirement.allowedRoles.includes(role));
104
118
 
105
119
  return {
106
120
  ...actor,
@@ -393,6 +393,7 @@ export function registerWorldRoutes(
393
393
  worldId: req.params.worldId,
394
394
  changes: req.body?.changes || null,
395
395
  enabled: Object.prototype.hasOwnProperty.call(req.body || {}, 'enabled') ? req.body.enabled : null,
396
+ status: req.body?.status || null,
396
397
  });
397
398
  res.json(result);
398
399
  } catch (error) {
@@ -27,7 +27,6 @@ export function buildWorldContextText({
27
27
  worldContextText = null,
28
28
  interactionRules = null,
29
29
  prohibitedRules = null,
30
- ratingRules = null,
31
30
  } = {}) {
32
31
  const explicitWorldContextText = normalizeText(worldContextText, null);
33
32
  if (explicitWorldContextText) return explicitWorldContextText;
@@ -41,7 +40,6 @@ export function buildWorldContextText({
41
40
  normalizeText(summary, null) ? `简介:${normalizeText(summary, null)}` : null,
42
41
  normalizeText(interactionRules, null) ? `互动规则:${normalizeText(interactionRules, null)}` : null,
43
42
  normalizeText(prohibitedRules, null) ? `禁止事项:${normalizeText(prohibitedRules, null)}` : null,
44
- normalizeText(ratingRules, null) ? `结果要求:${normalizeText(ratingRules, null)}` : null,
45
43
  ].filter(Boolean);
46
44
 
47
45
  return lines.length > 0 ? lines.join('\n') : null;
@@ -1,21 +0,0 @@
1
- import { createCanonicalResultBuilder } from '../../openclaw/runtime/canonical-result-builder.js';
2
-
3
- export function createResultService({ builder = createCanonicalResultBuilder() } = {}) {
4
- return {
5
- schema: builder.schema,
6
- previewConversation({ world, conversationKey = 'cnv_preview' } = {}) {
7
- const preview = builder.build({
8
- conversationId: conversationKey,
9
- intentSignals: world.resultContract.exampleSignals.intentSignals,
10
- conversationSignals: world.resultContract.exampleSignals.conversationSignals,
11
- agentSignals: world.resultContract.exampleSignals.agentSignals,
12
- });
13
- const rest = { ...preview };
14
- delete rest.conversationId;
15
- return {
16
- ...rest,
17
- conversationKey,
18
- };
19
- },
20
- };
21
- }