@xfxstudio/claworld 0.2.7 → 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.
@@ -1,5 +1,4 @@
1
1
  import { normalizeAgentProfile, resolveAgentDisplayName, resolveAgentVisibility } from '../../lib/agent-profile.js';
2
- import { normalizeChatRequestInput } from '../../lib/chat-request.js';
3
2
  import { createKickoffBrief, resolveStoredKickoffBrief } from '../../lib/relay/kickoff-text.js';
4
3
  import { WORLD_ACTIONS } from '../worlds/world-authorization.js';
5
4
  import { normalizeChatRequestApprovalPolicy } from '../contracts/chat-request-approval-policy.js';
@@ -282,92 +281,6 @@ function projectChatRequestOrigin(request = {}) {
282
281
  };
283
282
  }
284
283
 
285
- function hasConversationScope(conversation = null) {
286
- return Boolean(conversation && typeof conversation === 'object' && !Array.isArray(conversation) && Object.keys(conversation).length > 0);
287
- }
288
-
289
- function resolveConversationLinkRequest(requests = [], conversation = {}) {
290
- const conversationMeta = conversation?.meta && typeof conversation.meta === 'object' && !Array.isArray(conversation.meta)
291
- ? conversation.meta
292
- : {};
293
- const approvalRequestId = normalizeText(conversationMeta.approvalRequestId, null);
294
- if (approvalRequestId) {
295
- return requests.find((request) => normalizeText(request.chatRequestId || request.requestId, null) === approvalRequestId) || null;
296
- }
297
-
298
- const conversationKey = normalizeText(conversation?.conversationKey, null);
299
- if (!conversationKey) return null;
300
-
301
- return requests.find((request) => {
302
- const kickoff = request?.kickoff && typeof request.kickoff === 'object' && !Array.isArray(request.kickoff)
303
- ? request.kickoff
304
- : {};
305
- return normalizeText(kickoff.conversationKey, null) === conversationKey
306
- || normalizeText(request?.conversation?.conversationKey, null) === conversationKey;
307
- }) || null;
308
- }
309
-
310
- function resolveInboxChatDirection(viewerAgentId, request = null) {
311
- if (!request) return null;
312
- if (viewerAgentId === request.fromAgentId) return 'outbound';
313
- if (viewerAgentId === request.toAgentId) return 'inbound';
314
- return 'related';
315
- }
316
-
317
- function resolveInboxChatCounterpartyAgentId(viewerAgentId, request = null, conversation = null) {
318
- if (request) {
319
- if (viewerAgentId === request.fromAgentId) return request.toAgentId;
320
- if (viewerAgentId === request.toAgentId) return request.fromAgentId;
321
- }
322
-
323
- const participantIds = Array.isArray(conversation?.participantIds) ? conversation.participantIds : [];
324
- return participantIds.find((participantId) => participantId && participantId !== viewerAgentId) || null;
325
- }
326
-
327
- function resolveInboxChatStatus(conversation = {}, request = null) {
328
- const kickoffStatus = normalizeText(request?.kickoff?.status, null);
329
- if (kickoffStatus === 'sent') return 'opening';
330
- if (kickoffStatus === 'kept_silent') return 'silent';
331
- if (kickoffStatus === 'failed') return 'kickoff_failed';
332
- const conversationStatus = normalizeText(conversation?.status, 'active');
333
- if (conversationStatus === 'active') return 'active';
334
- if (conversationStatus === 'closed') return 'ended';
335
- return conversationStatus;
336
- }
337
-
338
- function resolveInboxConversationWorldSummary(worldService, request = {}, conversation = {}) {
339
- const requestContext = request?.requestContext && typeof request.requestContext === 'object' && !Array.isArray(request.requestContext)
340
- ? request.requestContext
341
- : {};
342
- const requestConversation = request?.conversation && typeof request.conversation === 'object' && !Array.isArray(request.conversation)
343
- ? request.conversation
344
- : {};
345
- const conversationMeta = conversation?.meta && typeof conversation.meta === 'object' && !Array.isArray(conversation.meta)
346
- ? conversation.meta
347
- : {};
348
- const worldMeta = conversationMeta.world && typeof conversationMeta.world === 'object' && !Array.isArray(conversationMeta.world)
349
- ? conversationMeta.world
350
- : {};
351
- const worldId = normalizeConversationWorldId(requestConversation.worldId)
352
- || normalizeConversationWorldId(requestContext.conversation?.worldId)
353
- || normalizeConversationWorldId(worldMeta.worldId)
354
- || normalizeConversationWorldId(conversationMeta.worldId);
355
-
356
- if (!worldId) {
357
- return {
358
- mode: 'direct',
359
- worldId: null,
360
- world: null,
361
- };
362
- }
363
-
364
- return {
365
- mode: 'world',
366
- worldId,
367
- world: projectWorldSummary(worldService, worldId),
368
- };
369
- }
370
-
371
284
  export function createChatRequestService({
372
285
  store = null,
373
286
  relay = null,
@@ -437,27 +350,8 @@ export function createChatRequestService({
437
350
  };
438
351
  }
439
352
 
440
- function projectChatInboxChat(conversation = {}, viewerAgentId = null, request = null) {
441
- const direction = resolveInboxChatDirection(viewerAgentId, request);
442
- const counterpartyAgentId = resolveInboxChatCounterpartyAgentId(viewerAgentId, request, conversation);
443
-
444
- return {
445
- chatRequestId: normalizeText(request?.chatRequestId || request?.requestId, null),
446
- status: resolveInboxChatStatus(conversation, request),
447
- ...(direction ? { direction } : {}),
448
- createdAt: normalizeText(conversation.createdAt, normalizeText(request?.createdAt, null)),
449
- updatedAt: normalizeText(conversation.updatedAt, null),
450
- lastTurnAt: normalizeText(conversation.lastTurnAt, null),
451
- conversationKey: normalizeText(conversation.conversationKey, null),
452
- localSessionKey: normalizeText(conversation.sessionKey, null),
453
- counterparty: projectAgent(assertStore(), counterpartyAgentId, presence),
454
- conversation: resolveInboxConversationWorldSummary(worldService, request, conversation),
455
- };
456
- }
457
-
458
353
  return {
459
354
  projectChatRequest,
460
- projectChatInboxChat,
461
355
  async syncApprovalPolicy({
462
356
  actorAgentId,
463
357
  credentialId = null,
@@ -495,7 +389,6 @@ export function createChatRequestService({
495
389
  openingMessage = null,
496
390
  openingPayload = null,
497
391
  worldId = null,
498
- requestContext = null,
499
392
  origin = null,
500
393
  broadcast = null,
501
394
  source = 'chat_request',
@@ -506,36 +399,29 @@ export function createChatRequestService({
506
399
  throw createInvalidChatRequestError('chat_request_target_required', 'chat request target requires targetAgentId');
507
400
  }
508
401
  const targetAgent = requireAgent(normalizedTargetAgentId);
509
- const normalizedSource = normalizeText(source, 'chat_request');
510
- const normalizedRequestInput = normalizeChatRequestInput({
511
- requestContext,
512
- source: normalizedSource,
513
- });
514
- const normalizedWorldId = normalizeConversationWorldId(worldId)
515
- || normalizeConversationWorldId(normalizedRequestInput.conversation?.worldId);
402
+ const normalizedWorldId = normalizeConversationWorldId(worldId);
516
403
  if (!targetAgent?.address) {
517
404
  throw createTargetAddressNotFoundError(normalizedTargetAgentId);
518
405
  }
519
- const normalizedOpeningPayload = cloneJsonObject(openingPayload) || cloneJsonObject(normalizedRequestInput.openingPayload);
406
+ const normalizedOpeningPayload = cloneJsonObject(openingPayload);
520
407
  const normalizedKickoffBrief = createKickoffBrief({
521
408
  text: typeof kickoffBrief === 'object' && kickoffBrief !== null && !Array.isArray(kickoffBrief)
522
409
  ? kickoffBrief.text
523
- : normalizeText(openingMessage, normalizeText(normalizedRequestInput.openingMessage, null)),
410
+ : openingMessage,
524
411
  payload: typeof kickoffBrief === 'object' && kickoffBrief !== null && !Array.isArray(kickoffBrief)
525
412
  ? kickoffBrief.payload
526
413
  : normalizedOpeningPayload,
527
414
  source: typeof kickoffBrief === 'object' && kickoffBrief !== null && !Array.isArray(kickoffBrief)
528
415
  ? kickoffBrief.source
529
- : normalizedSource === 'world_broadcast'
416
+ : source === 'world_broadcast'
530
417
  ? 'world_broadcast_brief'
531
418
  : 'chat_request_brief',
532
419
  });
533
- const normalizedOrigin = normalizeChatRequestOrigin(origin) || normalizeChatRequestOrigin(normalizedRequestInput.origin);
534
- const normalizedBroadcast = normalizeChatRequestBroadcastMetadata(broadcast)
535
- || normalizeChatRequestBroadcastMetadata(normalizedRequestInput.broadcast);
420
+ const normalizedOrigin = normalizeChatRequestOrigin(origin);
421
+ const normalizedBroadcast = normalizeChatRequestBroadcastMetadata(broadcast);
536
422
  if (normalizedWorldId) {
537
423
  worldService?.requireWorld?.(normalizedWorldId);
538
- if (normalizedSource !== 'world_broadcast') {
424
+ if (normalizeText(source, 'chat_request') !== 'world_broadcast') {
539
425
  const authorization = worldAuthorizationService.evaluateWorldAction({
540
426
  worldId: normalizedWorldId,
541
427
  actorAgentId: fromAgentId,
@@ -559,10 +445,9 @@ export function createChatRequestService({
559
445
  conversation: {
560
446
  ...(normalizedWorldId ? { worldId: normalizedWorldId } : {}),
561
447
  },
562
- requestContext: cloneJsonObject(requestContext),
563
448
  origin: normalizedOrigin,
564
449
  broadcast: normalizedBroadcast,
565
- source: normalizedSource,
450
+ source: normalizeText(source, 'chat_request'),
566
451
  });
567
452
  if (result.status < 200 || result.status >= 300) {
568
453
  throw createRelayResponseError(result, 'chat_request_create_failed');
@@ -610,55 +495,23 @@ export function createChatRequestService({
610
495
  };
611
496
  },
612
497
 
613
- listChatInbox({ agentId, direction = null } = {}) {
498
+ listChatRequests({ agentId, direction = null } = {}) {
614
499
  requireAgent(agentId);
615
500
  const normalizedDirection = normalizeDirection(direction);
616
- let requests = assertStore().listChatRequests ? assertStore().listChatRequests() : [];
617
- requests = requests.filter((request) => request.fromAgentId === agentId || request.toAgentId === agentId);
501
+ let items = assertStore().listChatRequests ? assertStore().listChatRequests() : [];
502
+ items = items.filter((request) => request.status === 'pending');
503
+ items = items.filter((request) => request.fromAgentId === agentId || request.toAgentId === agentId);
618
504
  if (normalizedDirection === 'inbound') {
619
- requests = requests.filter((request) => request.toAgentId === agentId);
505
+ items = items.filter((request) => request.toAgentId === agentId);
620
506
  } else if (normalizedDirection === 'outbound') {
621
- requests = requests.filter((request) => request.fromAgentId === agentId);
507
+ items = items.filter((request) => request.fromAgentId === agentId);
622
508
  }
623
509
 
624
- const pendingRequests = sortByRecency(
625
- requests.filter((request) => request.status === 'pending'),
626
- 'createdAt',
627
- ).map((request) => projectChatRequest(request, agentId));
628
-
629
- const conversations = assertStore().listConversations
630
- ? assertStore().listConversations({ participantId: agentId })
631
- : [];
632
- const chats = sortByRecency(
633
- conversations
634
- .map((conversation) => {
635
- const linkedRequest = resolveConversationLinkRequest(requests, conversation);
636
- if (!linkedRequest && !normalizeText(conversation?.meta?.approvalRequestId, null)) return null;
637
- const projected = projectChatInboxChat(conversation, agentId, linkedRequest);
638
- if (!projected) return null;
639
- if (normalizedDirection && projected.direction !== normalizedDirection) return null;
640
- return projected;
641
- })
642
- .filter(Boolean),
643
- 'lastTurnAt',
644
- 'updatedAt',
645
- 'createdAt',
646
- );
647
-
648
510
  return {
649
- counts: {
650
- pendingRequestCount: pendingRequests.length,
651
- chatCount: chats.length,
652
- },
653
- pendingRequests,
654
- chats,
511
+ items: sortByRecency(items, 'createdAt').map((request) => projectChatRequest(request, agentId)),
655
512
  };
656
513
  },
657
514
 
658
- listChatRequests({ agentId, direction = null } = {}) {
659
- return this.listChatInbox({ agentId, direction });
660
- },
661
-
662
515
  async acceptChatRequest(chatRequestId, { actorAgentId } = {}) {
663
516
  requireAgent(actorAgentId);
664
517
  const normalizedChatRequestId = normalizeText(chatRequestId, null);
@@ -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;
@@ -154,7 +184,7 @@ function buildWorldRecord({
154
184
  status = null,
155
185
  existingMetrics = null,
156
186
  } = {}) {
157
- const resolvedStatus = status || (enabled ? 'enabled' : 'draft');
187
+ const resolvedStatus = normalizeOwnerWorldStatus(status, enabled ? 'enabled' : 'draft');
158
188
  const participantContextField = buildDefaultEntryProfileField();
159
189
  const resolvedWorldContextText = buildWorldContextText({
160
190
  worldId,
@@ -186,7 +216,7 @@ function buildWorldRecord({
186
216
  matching: buildMatchingStrategy(),
187
217
  conversationTemplate: buildConversationTemplate(null, null),
188
218
  meta: {
189
- status: resolvedStatus === 'enabled' ? 'creator_enabled' : 'creator_draft',
219
+ status: projectOwnerWorldMetaStatus(resolvedStatus, enabled),
190
220
  persistence: 'store',
191
221
  },
192
222
  creatorAgentId,
@@ -314,6 +344,7 @@ export function createWorldAdminService({ worldService, worldAuthorizationServic
314
344
  displayName,
315
345
  worldContextText,
316
346
  enabled = false,
347
+ status = null,
317
348
  } = {}) {
318
349
  const storeBacked = assertStore();
319
350
  const resolvedOwnerAgentId = assertActorAgent(ownerAgentId || creatorAgentId);
@@ -330,6 +361,7 @@ export function createWorldAdminService({ worldService, worldAuthorizationServic
330
361
  summary: summarizeWorldContextText(resolvedWorldContextText, resolvedDisplayName),
331
362
  worldContextText: resolvedWorldContextText,
332
363
  enabled: normalizeBoolean(enabled, false),
364
+ status: normalizeOwnerWorldStatus(status, normalizeBoolean(enabled, false) ? 'enabled' : 'draft'),
333
365
  });
334
366
 
335
367
  const created = await storeBacked.createWorldConfig(worldRecord);
@@ -367,10 +399,14 @@ export function createWorldAdminService({ worldService, worldAuthorizationServic
367
399
  worldRole: authorization.worldRole,
368
400
  });
369
401
  },
370
- async manageWorld({ actorAgentId, creatorAgentId, worldId, changes = null, enabled = null } = {}) {
402
+ async manageWorld({ actorAgentId, creatorAgentId, worldId, changes = null, enabled = null, status = null } = {}) {
371
403
  const storeBacked = assertStore();
372
404
  const resolvedActorAgentId = assertActorAgent(actorAgentId || creatorAgentId);
373
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));
374
410
 
375
411
  const authorization = requireWorldOwner({
376
412
  worldId,
@@ -378,7 +414,7 @@ export function createWorldAdminService({ worldService, worldAuthorizationServic
378
414
  });
379
415
 
380
416
  const existingWorld = authorization.world;
381
- if (!hasChanges && enabled == null) {
417
+ if (!hasChanges && resolvedEnabled == null && normalizedStatus == null) {
382
418
  return projectManagedWorld(storeBacked, existingWorld, {
383
419
  worldRole: authorization.worldRole,
384
420
  });
@@ -397,20 +433,24 @@ export function createWorldAdminService({ worldService, worldAuthorizationServic
397
433
  displayName: nextDisplayName,
398
434
  summary: summarizeWorldContextText(nextWorldContextText, nextDisplayName),
399
435
  worldContextText: nextWorldContextText,
400
- enabled: enabled == null ? existingWorld.enabled === true : normalizeBoolean(enabled, false),
401
- status: enabled == null
402
- ? existingWorld.status
403
- : (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
+ ),
404
442
  existingMetrics: existingWorld.metrics || null,
405
443
  });
406
- } 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');
407
447
  nextRecord = {
408
448
  ...existingWorld,
409
- enabled: normalizeBoolean(enabled, false),
410
- status: normalizeBoolean(enabled, false) ? 'enabled' : 'disabled',
449
+ enabled: nextEnabled,
450
+ status: nextStatus,
411
451
  meta: {
412
452
  ...(existingWorld.meta || {}),
413
- status: normalizeBoolean(enabled, false) ? 'creator_enabled' : 'creator_disabled',
453
+ status: projectOwnerWorldMetaStatus(nextStatus, nextEnabled),
414
454
  },
415
455
  };
416
456
  }
@@ -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) {