@xfxstudio/claworld 0.2.13 → 0.2.15

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 (58) hide show
  1. package/README.md +4 -4
  2. package/index.js +0 -1
  3. package/openclaw.plugin.json +1 -97
  4. package/package.json +1 -1
  5. package/skills/claworld-help/SKILL.md +47 -27
  6. package/skills/claworld-join-and-chat/SKILL.md +13 -9
  7. package/src/openclaw/index.js +0 -3
  8. package/src/openclaw/plugin/account-identity.js +0 -1
  9. package/src/openclaw/plugin/claworld-channel-plugin.js +73 -319
  10. package/src/openclaw/plugin/config-schema.js +1 -55
  11. package/src/openclaw/plugin/managed-config.js +1 -42
  12. package/src/openclaw/plugin/onboarding.js +1 -1
  13. package/src/openclaw/plugin/register.js +302 -233
  14. package/src/openclaw/plugin/relay-client.js +9 -6
  15. package/src/openclaw/runtime/product-shell-helper.js +11 -364
  16. package/src/openclaw/runtime/tool-contracts.js +0 -182
  17. package/src/openclaw/runtime/tool-inventory.js +4 -27
  18. package/src/lib/agent-profile.js +0 -74
  19. package/src/lib/http-auth.js +0 -151
  20. package/src/lib/policy.js +0 -114
  21. package/src/openclaw/installer/constants.js +0 -14
  22. package/src/product-shell/agent-cards/card-routes.js +0 -64
  23. package/src/product-shell/agent-cards/card-service.js +0 -287
  24. package/src/product-shell/agent-cards/spec-builder.js +0 -167
  25. package/src/product-shell/agent-cards/storage/image-host-storage.js +0 -192
  26. package/src/product-shell/agent-cards/storage/local-public-storage.js +0 -74
  27. package/src/product-shell/agent-cards/svg-renderer.js +0 -325
  28. package/src/product-shell/agent-cards/template-registry.js +0 -131
  29. package/src/product-shell/catalog/default-world-catalog.js +0 -38
  30. package/src/product-shell/contracts/candidate-feed.js +0 -393
  31. package/src/product-shell/contracts/world-manifest.js +0 -369
  32. package/src/product-shell/conversation-feedback/conversation-feedback-service.js +0 -261
  33. package/src/product-shell/feedback/feedback-contract.js +0 -13
  34. package/src/product-shell/feedback/feedback-routes.js +0 -98
  35. package/src/product-shell/feedback/feedback-service.js +0 -252
  36. package/src/product-shell/index.js +0 -212
  37. package/src/product-shell/matching/matchmaking-service.js +0 -395
  38. package/src/product-shell/membership/membership-service.js +0 -284
  39. package/src/product-shell/onboarding/onboarding-routes.js +0 -37
  40. package/src/product-shell/onboarding/onboarding-service.js +0 -222
  41. package/src/product-shell/orchestration/world-conversation-orchestrator.js +0 -28
  42. package/src/product-shell/profile/profile-service.js +0 -142
  43. package/src/product-shell/profile/public-identity-routes.js +0 -160
  44. package/src/product-shell/profile/public-identity-service.js +0 -192
  45. package/src/product-shell/search/search-service.js +0 -393
  46. package/src/product-shell/social/chat-request-approval-policy.js +0 -332
  47. package/src/product-shell/social/chat-request-routes.js +0 -130
  48. package/src/product-shell/social/chat-request-service.js +0 -723
  49. package/src/product-shell/social/friend-routes.js +0 -82
  50. package/src/product-shell/social/friend-service.js +0 -557
  51. package/src/product-shell/social/social-routes.js +0 -21
  52. package/src/product-shell/social/social-service.js +0 -136
  53. package/src/product-shell/worlds/world-admin-service.js +0 -486
  54. package/src/product-shell/worlds/world-authorization.js +0 -136
  55. package/src/product-shell/worlds/world-broadcast-service.js +0 -296
  56. package/src/product-shell/worlds/world-routes.js +0 -403
  57. package/src/product-shell/worlds/world-service.js +0 -89
  58. package/src/product-shell/worlds/world-text.js +0 -75
@@ -1,6 +1,5 @@
1
1
  import { EventEmitter } from 'events';
2
2
  import WebSocket from 'ws';
3
- import { v4 as uuidv4 } from 'uuid';
4
3
  import { resolveClaworldRuntimeConfig } from './config-schema.js';
5
4
  import { buildRuntimeAuthHeaders } from './account-identity.js';
6
5
  import { createRelayEventProtocol } from '../protocol/relay-event-protocol.js';
@@ -60,8 +59,12 @@ function normalizeOptionalText(value) {
60
59
  return normalized || null;
61
60
  }
62
61
 
63
- function resolveClientMessageId(value = null) {
64
- return normalizeOptionalText(value) || `cmsg_${uuidv4()}`;
62
+ function requireClientMessageId(value = null) {
63
+ const normalized = normalizeOptionalText(value);
64
+ if (!normalized) {
65
+ throw new Error('claworld relay clientMessageId is required for POST /v1/messages');
66
+ }
67
+ return normalized;
65
68
  }
66
69
 
67
70
  function buildReplyAckTimeoutError({ deliveryId, timeoutMs, context = {} } = {}) {
@@ -584,7 +587,7 @@ export class ClaworldRelayClient extends EventEmitter {
584
587
  config,
585
588
  agentId,
586
589
  credential = null,
587
- clientVersion = 'claworld-plugin/0.2.8',
590
+ clientVersion = 'claworld-plugin/0.2.15',
588
591
  sessionTarget,
589
592
  fallbackTarget,
590
593
  } = {}) {
@@ -1376,7 +1379,7 @@ export class ClaworldRelayClient extends EventEmitter {
1376
1379
  }
1377
1380
 
1378
1381
  async deliverMessage({ fromAgentId, targetAgentId, clientMessageId = null, payload = {}, conversation = {} } = {}) {
1379
- const resolvedClientMessageId = resolveClientMessageId(clientMessageId);
1382
+ const resolvedClientMessageId = requireClientMessageId(clientMessageId);
1380
1383
  const result = await this.requestJson('/v1/messages', {
1381
1384
  method: 'POST',
1382
1385
  headers: buildRuntimeAuthHeaders(this.runtimeConfig, { 'content-type': 'application/json' }),
@@ -1439,7 +1442,7 @@ export class ClaworldRelayClient extends EventEmitter {
1439
1442
  if (requestResult.status !== 201) {
1440
1443
  throw new Error(`failed to create chat request: ${JSON.stringify(requestResult.body)}`);
1441
1444
  }
1442
- const requestId = requestResult.body.requestId;
1445
+ const requestId = requestResult.body?.chatRequest?.chatRequestId || requestResult.body?.requestId || null;
1443
1446
  return {
1444
1447
  requestId,
1445
1448
  sessionKey: null,
@@ -1,10 +1,8 @@
1
1
  import { resolveClaworldRuntimeConfig } from '../plugin/config-schema.js';
2
- import { buildRuntimeAuthHeaders } from '../plugin/account-identity.js';
3
2
  import { createRuntimeBoundaryError } from '../../lib/runtime-errors.js';
4
3
  import { extractBackendErrorContext } from './backend-error-context.js';
5
4
  import {
6
5
  buildCandidateDeliverySummary as buildBackendCandidateDeliverySummary,
7
- buildWorldSelectionPrompt as buildBackendWorldSelectionPrompt,
8
6
  resolveWorldSelection as resolveBackendWorldSelection,
9
7
  } from '../../product-shell/contracts/world-orchestration.js';
10
8
 
@@ -25,15 +23,6 @@ function normalizeStringList(values = []) {
25
23
  return [...new Set(values.map((value) => normalizeText(value, null)).filter(Boolean))];
26
24
  }
27
25
 
28
- function normalizeBroadcastConfig(broadcast = {}) {
29
- return {
30
- enabled: broadcast.enabled === true,
31
- audience: normalizeText(broadcast.audience, 'members'),
32
- replyPolicy: normalizeText(broadcast.replyPolicy, 'zero'),
33
- excludeSelf: broadcast.excludeSelf !== false,
34
- };
35
- }
36
-
37
26
  function isEmptyProfileValue(value) {
38
27
  if (value == null) return true;
39
28
  if (typeof value === 'string') return value.trim() === '';
@@ -416,88 +405,15 @@ function normalizeWorldJoinResponse(payload = {}, { worldId = null, agentId = nu
416
405
  ? payload.nextStageSummary
417
406
  : {},
418
407
  candidateFeed,
419
- candidateDelivery:
420
- payload.candidateDelivery && typeof payload.candidateDelivery === 'object'
421
- ? payload.candidateDelivery
422
- : (candidateFeed ? buildCandidateDeliverySummary(candidateFeed) : null),
408
+ candidateDelivery: payload.candidateDelivery && typeof payload.candidateDelivery === 'object'
409
+ ? payload.candidateDelivery
410
+ : null,
423
411
  orchestration: payload.orchestration && typeof payload.orchestration === 'object'
424
412
  ? payload.orchestration
425
413
  : null,
426
414
  };
427
415
  }
428
416
 
429
- function normalizeSearchMatchedField(field = {}, index = 0) {
430
- return {
431
- fieldId: normalizeText(field.fieldId, `field_${index + 1}`),
432
- label: normalizeText(field.label, `Field ${index + 1}`),
433
- matchType: normalizeText(field.matchType, 'exact'),
434
- queryValue: field.queryValue ?? null,
435
- candidateValue: field.candidateValue ?? null,
436
- sharedValues: Array.isArray(field.sharedValues) ? normalizeStringList(field.sharedValues) : [],
437
- contribution: normalizeNumber(field.contribution, 0),
438
- };
439
- }
440
-
441
- function normalizeWorldSearchItem(item = {}, index = 0) {
442
- const resolvedAgentId = normalizeText(item.agentId, normalizeText(item.playerId, `agent_${index + 1}`));
443
- return {
444
- agentId: resolvedAgentId,
445
- playerId: normalizeText(item.playerId, resolvedAgentId),
446
- membershipId: normalizeText(item.membershipId, null),
447
- worldId: normalizeText(item.worldId, 'unknown-world'),
448
- displayName: normalizeText(item.displayName, `Player ${index + 1}`),
449
- headline: normalizeText(item.headline, null),
450
- online: item.online === true,
451
- connectedAt: normalizeText(item.connectedAt, null),
452
- lastHeartbeatAt: normalizeText(item.lastHeartbeatAt, null),
453
- score: normalizeNumber(item.score, 0),
454
- matchedFieldIds: normalizeStringList(item.matchedFieldIds),
455
- matchedFields: Array.isArray(item.matchedFields)
456
- ? item.matchedFields.map((field, fieldIndex) => normalizeSearchMatchedField(field, fieldIndex))
457
- : [],
458
- resultType: normalizeText(item.resultType, 'matched'),
459
- reasonSummary: normalizeText(item.reasonSummary, ''),
460
- joinedAt: normalizeText(item.joinedAt, null),
461
- profileSummary: normalizeCandidateProfileSummary(item.profileSummary),
462
- worldFeedbackSummary: item.worldFeedbackSummary && typeof item.worldFeedbackSummary === 'object'
463
- ? {
464
- likesReceived: normalizeInteger(item.worldFeedbackSummary.likesReceived, 0),
465
- dislikesReceived: normalizeInteger(item.worldFeedbackSummary.dislikesReceived, 0),
466
- }
467
- : {
468
- likesReceived: 0,
469
- dislikesReceived: 0,
470
- },
471
- };
472
- }
473
-
474
- function normalizeWorldSearchResponse(payload = {}, { worldId = null, agentId = null } = {}) {
475
- const items = Array.isArray(payload.items)
476
- ? payload.items.map((item, index) => normalizeWorldSearchItem(item, index))
477
- : [];
478
-
479
- return {
480
- worldId: normalizeText(payload.worldId, worldId || 'unknown-world'),
481
- agentId: normalizeText(payload.agentId, agentId || null),
482
- viewerMembershipId: normalizeText(payload.viewerMembershipId, null),
483
- searchModel: normalizeSearchSchema(payload.searchModel || {}, {
484
- worldId: normalizeText(payload.worldId, worldId || 'unknown-world'),
485
- fallbackFields: [],
486
- }),
487
- searchInput: normalizeProfile(payload.searchInput && typeof payload.searchInput === 'object' ? payload.searchInput : {}),
488
- onlineOnly: payload.onlineOnly !== false,
489
- candidateSource: normalizeText(payload.candidateSource, 'active_memberships_online'),
490
- limit: normalizeInteger(payload.limit, items.length),
491
- totalMatches: normalizeInteger(payload.totalMatches, items.length),
492
- status: normalizeText(payload.status, items.length > 0 ? 'search_ready' : 'no_matches'),
493
- nextAction: normalizeText(
494
- payload.nextAction,
495
- items.length > 0 ? 'request_chat_with_selected_candidate' : 'broaden_search_or_wait',
496
- ),
497
- items,
498
- };
499
- }
500
-
501
417
  function summarizeProfileValue(value) {
502
418
  if (Array.isArray(value)) return joinAsNaturalLanguage(value.map((entry) => String(entry).trim()).filter(Boolean));
503
419
  return normalizeText(value, '');
@@ -524,8 +440,6 @@ export function buildCandidateDeliverySummary(candidateFeed = {}, { worldDetail
524
440
  if (worldDetail?.candidateDelivery && typeof worldDetail.candidateDelivery === 'object') {
525
441
  return worldDetail.candidateDelivery;
526
442
  }
527
- // Older responses may still omit candidateDelivery; keep the shared builder as
528
- // a compatibility fallback, not the canonical orchestration owner.
529
443
  return buildBackendCandidateDeliverySummary(candidateFeed, { worldDetail, limit });
530
444
  }
531
445
 
@@ -597,12 +511,9 @@ function buildSelectionRetryContract(status, selection, items = [], matches = []
597
511
  }
598
512
 
599
513
  export function buildWorldSelectionPrompt(worldDirectory = {}) {
600
- if (worldDirectory?.orchestration && typeof worldDirectory.orchestration === 'object') {
601
- return worldDirectory.orchestration;
602
- }
603
- // Compatibility fallback for older directory payloads that predate
604
- // backend-authored orchestration.
605
- return buildBackendWorldSelectionPrompt(worldDirectory);
514
+ return worldDirectory?.orchestration && typeof worldDirectory.orchestration === 'object'
515
+ ? worldDirectory.orchestration
516
+ : null;
606
517
  }
607
518
 
608
519
  export function buildPostSetupWorldDirectory(payload = {}, { accountId = null } = {}) {
@@ -632,7 +543,7 @@ export function buildPostSetupWorldDirectory(payload = {}, { accountId = null }
632
543
  sort,
633
544
  orchestration: payload.orchestration && typeof payload.orchestration === 'object'
634
545
  ? payload.orchestration
635
- : buildWorldSelectionPrompt({ items, recommendedWorldId }),
546
+ : null,
636
547
  };
637
548
  }
638
549
 
@@ -709,56 +620,6 @@ function createProductShellHttpError(action, response, { accountId = null, world
709
620
  });
710
621
  }
711
622
 
712
- function normalizeBroadcastRequestPayload(payload = {}, { message = null } = {}) {
713
- const normalizedPayload = payload && typeof payload === 'object' && !Array.isArray(payload)
714
- ? { ...payload }
715
- : {};
716
- const normalizedMessage = normalizeText(message, null);
717
- if (!normalizedMessage) return normalizedPayload;
718
- return {
719
- ...normalizedPayload,
720
- ...(normalizedPayload.text == null ? { text: normalizedMessage } : {}),
721
- };
722
- }
723
-
724
- function normalizeBroadcastResult(payload = {}) {
725
- const requests = Array.isArray(payload.requests)
726
- ? payload.requests.map((request) => ({
727
- agentId: normalizeText(request.agentId, null),
728
- status: normalizeText(request.status, 'created'),
729
- chatRequest: request.chatRequest && typeof request.chatRequest === 'object' && !Array.isArray(request.chatRequest)
730
- ? request.chatRequest
731
- : null,
732
- }))
733
- : [];
734
- const failures = Array.isArray(payload.failures)
735
- ? payload.failures.map((failure) => ({
736
- agentId: normalizeText(failure.agentId, null),
737
- status: normalizeText(failure.status, 'failed'),
738
- httpStatus: normalizeInteger(failure.httpStatus, 0),
739
- error: normalizeText(failure.error, null),
740
- reason: normalizeText(failure.reason, null),
741
- message: normalizeText(failure.message, null),
742
- }))
743
- : [];
744
- return {
745
- status: normalizeText(payload.status, 'requests_created'),
746
- worldId: normalizeText(payload.worldId, null),
747
- senderAgentId: normalizeText(payload.senderAgentId, null),
748
- senderRole: normalizeText(payload.senderRole, 'none'),
749
- audience: normalizeText(payload.audience, 'members'),
750
- excludeSelf: payload.excludeSelf !== false,
751
- eligibility: normalizeText(payload.eligibility, 'active'),
752
- broadcastId: normalizeText(payload.broadcastId, null),
753
- totalTargets: normalizeInteger(payload.totalTargets, 0),
754
- createdCount: normalizeInteger(payload.createdCount, requests.length),
755
- failedCount: normalizeInteger(payload.failedCount, failures.length),
756
- nextAction: normalizeText(payload.nextAction, 'recipients_review_pending_requests'),
757
- requests,
758
- failures,
759
- };
760
- }
761
-
762
623
  export async function fetchWorldDetail({
763
624
  cfg = {},
764
625
  accountId = null,
@@ -782,7 +643,7 @@ export async function fetchWorldDetail({
782
643
  headers: {
783
644
  accept: 'application/json',
784
645
  ...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
785
- ...(resolvedRuntimeConfig.relay?.credentialToken ? { 'x-relay-token': resolvedRuntimeConfig.relay.credentialToken } : {}),
646
+ ...(resolvedRuntimeConfig.relay?.credentialToken ? { authorization: `Bearer ${resolvedRuntimeConfig.relay.credentialToken}` } : {}),
786
647
  },
787
648
  });
788
649
 
@@ -834,7 +695,7 @@ export async function joinWorld({
834
695
  accept: 'application/json',
835
696
  'content-type': 'application/json',
836
697
  ...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
837
- ...(resolvedRuntimeConfig.relay?.credentialToken ? { 'x-relay-token': resolvedRuntimeConfig.relay.credentialToken } : {}),
698
+ ...(resolvedRuntimeConfig.relay?.credentialToken ? { authorization: `Bearer ${resolvedRuntimeConfig.relay.credentialToken}` } : {}),
838
699
  },
839
700
  body: JSON.stringify({
840
701
  agentId: resolvedAgentId,
@@ -862,220 +723,6 @@ export async function joinWorld({
862
723
  });
863
724
  }
864
725
 
865
- export async function fetchWorldSearch({
866
- cfg = {},
867
- accountId = null,
868
- runtimeConfig = null,
869
- worldId = null,
870
- agentId = null,
871
- query = {},
872
- limit = null,
873
- fetchImpl,
874
- logger = console,
875
- } = {}) {
876
- if (typeof fetchImpl !== 'function') {
877
- throw new Error('fetch is unavailable for claworld product-shell world search helper');
878
- }
879
-
880
- const resolvedWorldId = normalizeText(worldId, null);
881
- if (!resolvedWorldId) {
882
- throw new Error('claworld product-shell world search helper requires worldId');
883
- }
884
-
885
- const resolvedAgentId = normalizeText(agentId, null);
886
- if (!resolvedAgentId) {
887
- throw new Error('claworld product-shell world search helper requires agentId');
888
- }
889
-
890
- const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
891
- const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
892
- const normalizedQuery = normalizeProfile(query);
893
- const searchResult = await fetchJson(fetchImpl, `${baseUrl}/v1/worlds/${encodeURIComponent(resolvedWorldId)}/search`, {
894
- method: 'POST',
895
- headers: {
896
- accept: 'application/json',
897
- 'content-type': 'application/json',
898
- ...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
899
- ...(resolvedRuntimeConfig.relay?.credentialToken ? { 'x-relay-token': resolvedRuntimeConfig.relay.credentialToken } : {}),
900
- },
901
- body: JSON.stringify({
902
- agentId: resolvedAgentId,
903
- query: normalizedQuery,
904
- ...(limit != null ? { limit } : {}),
905
- }),
906
- });
907
-
908
- if (!searchResult.ok) {
909
- logger.error?.('[claworld:product-shell] world search failed', {
910
- status: searchResult.status,
911
- worldId: resolvedWorldId,
912
- agentId: resolvedAgentId,
913
- accountId: resolvedRuntimeConfig.accountId || accountId || null,
914
- body: searchResult.body,
915
- });
916
- throw createProductShellHttpError('world_search', searchResult, {
917
- accountId: resolvedRuntimeConfig.accountId || accountId || null,
918
- worldId: resolvedWorldId,
919
- });
920
- }
921
-
922
- return normalizeWorldSearchResponse(searchResult.body, {
923
- worldId: resolvedWorldId,
924
- agentId: resolvedAgentId,
925
- });
926
- }
927
-
928
- export async function submitWorldSearch({
929
- cfg = {},
930
- accountId = null,
931
- runtimeConfig = null,
932
- worldId = null,
933
- agentId = null,
934
- query = {},
935
- limit = null,
936
- fetchImpl,
937
- logger = console,
938
- } = {}) {
939
- if (typeof fetchImpl !== 'function') {
940
- throw new Error('fetch is unavailable for claworld product-shell world search helper');
941
- }
942
-
943
- const resolvedWorldId = normalizeText(worldId, null);
944
- if (!resolvedWorldId) {
945
- throw new Error('claworld product-shell world search helper requires worldId');
946
- }
947
-
948
- const resolvedAgentId = normalizeText(agentId, null);
949
- if (!resolvedAgentId) {
950
- throw new Error('claworld product-shell world search helper requires agentId');
951
- }
952
-
953
- const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
954
- const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
955
- const normalizedQuery = normalizeProfile(query);
956
- const searchResult = await fetchJson(fetchImpl, `${baseUrl}/v1/worlds/${encodeURIComponent(resolvedWorldId)}/search`, {
957
- method: 'POST',
958
- headers: {
959
- accept: 'application/json',
960
- 'content-type': 'application/json',
961
- ...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
962
- ...(resolvedRuntimeConfig.relay?.credentialToken ? { 'x-relay-token': resolvedRuntimeConfig.relay.credentialToken } : {}),
963
- },
964
- body: JSON.stringify({
965
- agentId: resolvedAgentId,
966
- query: normalizedQuery,
967
- ...(limit != null ? { limit } : {}),
968
- }),
969
- });
970
-
971
- if (!searchResult.ok && searchResult.status !== 409) {
972
- logger.error?.('[claworld:product-shell] world search failed', {
973
- status: searchResult.status,
974
- worldId: resolvedWorldId,
975
- agentId: resolvedAgentId,
976
- accountId: resolvedRuntimeConfig.accountId || accountId || null,
977
- body: searchResult.body,
978
- });
979
- throw createProductShellHttpError('world_search', searchResult, {
980
- accountId: resolvedRuntimeConfig.accountId || accountId || null,
981
- worldId: resolvedWorldId,
982
- });
983
- }
984
-
985
- if (searchResult.status === 409) {
986
- return {
987
- status: 'not_joined',
988
- worldId: resolvedWorldId,
989
- agentId: resolvedAgentId,
990
- searchEnabled: false,
991
- results: [],
992
- query: normalizedQuery,
993
- limit: normalizeInteger(limit, 10),
994
- message: 'Join the world successfully before using world search.',
995
- };
996
- }
997
-
998
- const normalizedSearch = normalizeWorldSearchResponse(searchResult.body, {
999
- worldId: resolvedWorldId,
1000
- agentId: resolvedAgentId,
1001
- });
1002
-
1003
- return {
1004
- ...normalizedSearch,
1005
- status: normalizedSearch.items.length > 0 ? 'ready' : 'empty',
1006
- searchEnabled: true,
1007
- results: normalizedSearch.items,
1008
- query: normalizedSearch.searchInput,
1009
- };
1010
- }
1011
-
1012
- export async function broadcastWorld({
1013
- cfg = {},
1014
- accountId = null,
1015
- runtimeConfig = null,
1016
- worldId = null,
1017
- agentId = null,
1018
- message = null,
1019
- payload = {},
1020
- audience = null,
1021
- excludeSelf = null,
1022
- fetchImpl,
1023
- logger = console,
1024
- } = {}) {
1025
- if (typeof fetchImpl !== 'function') {
1026
- throw new Error('fetch is unavailable for claworld product-shell world broadcast helper');
1027
- }
1028
-
1029
- const resolvedWorldId = normalizeText(worldId, null);
1030
- if (!resolvedWorldId) {
1031
- throw new Error('claworld product-shell world broadcast helper requires worldId');
1032
- }
1033
-
1034
- const resolvedAgentId = normalizeText(agentId, null);
1035
- if (!resolvedAgentId) {
1036
- throw new Error('claworld product-shell world broadcast helper requires agentId');
1037
- }
1038
-
1039
- const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
1040
- const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
1041
- const requestBody = {
1042
- agentId: resolvedAgentId,
1043
- payload: normalizeBroadcastRequestPayload(payload, { message }),
1044
- ...(audience ? { audience } : {}),
1045
- ...(excludeSelf == null ? {} : { excludeSelf: excludeSelf === true }),
1046
- };
1047
- const broadcastResult = await fetchJson(
1048
- fetchImpl,
1049
- `${baseUrl}/v1/worlds/${encodeURIComponent(resolvedWorldId)}/broadcast`,
1050
- {
1051
- method: 'POST',
1052
- headers: {
1053
- accept: 'application/json',
1054
- 'content-type': 'application/json',
1055
- ...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
1056
- ...(resolvedRuntimeConfig.relay?.credentialToken ? { 'x-relay-token': resolvedRuntimeConfig.relay.credentialToken } : {}),
1057
- },
1058
- body: JSON.stringify(requestBody),
1059
- },
1060
- );
1061
-
1062
- if (!broadcastResult.ok) {
1063
- logger.error?.('[claworld:product-shell] world broadcast failed', {
1064
- status: broadcastResult.status,
1065
- worldId: resolvedWorldId,
1066
- agentId: resolvedAgentId,
1067
- accountId: resolvedRuntimeConfig.accountId || accountId || null,
1068
- body: broadcastResult.body,
1069
- });
1070
- throw createProductShellHttpError('world_broadcast', broadcastResult, {
1071
- accountId: resolvedRuntimeConfig.accountId || accountId || null,
1072
- worldId: resolvedWorldId,
1073
- });
1074
- }
1075
-
1076
- return normalizeBroadcastResult(broadcastResult.body);
1077
- }
1078
-
1079
726
  export async function fetchWorldCandidateFeed({
1080
727
  cfg = {},
1081
728
  accountId = null,
@@ -1112,7 +759,7 @@ export async function fetchWorldCandidateFeed({
1112
759
  headers: {
1113
760
  accept: 'application/json',
1114
761
  ...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
1115
- ...(resolvedRuntimeConfig.relay?.credentialToken ? { 'x-relay-token': resolvedRuntimeConfig.relay.credentialToken } : {}),
762
+ ...(resolvedRuntimeConfig.relay?.credentialToken ? { authorization: `Bearer ${resolvedRuntimeConfig.relay.credentialToken}` } : {}),
1116
763
  },
1117
764
  });
1118
765
 
@@ -1158,7 +805,7 @@ export async function resolveWorldSelectionFlow({
1158
805
  headers: {
1159
806
  accept: 'application/json',
1160
807
  ...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
1161
- ...(resolvedRuntimeConfig.relay?.credentialToken ? { 'x-relay-token': resolvedRuntimeConfig.relay.credentialToken } : {}),
808
+ ...(resolvedRuntimeConfig.relay?.credentialToken ? { authorization: `Bearer ${resolvedRuntimeConfig.relay.credentialToken}` } : {}),
1162
809
  },
1163
810
  });
1164
811