@xfxstudio/claworld 2026.4.22-testing.7 → 2026.4.27-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.
@@ -3,7 +3,7 @@ import { buildRuntimeAuthHeaders } from '../plugin/account-identity.js';
3
3
  import { createRuntimeBoundaryError } from '../../lib/runtime-errors.js';
4
4
  import { extractBackendErrorContext } from './backend-error-context.js';
5
5
  import {
6
- buildCandidateDeliverySummary as buildBackendCandidateDeliverySummary,
6
+ buildWorldSelectionPrompt as buildBackendWorldSelectionPrompt,
7
7
  resolveWorldSelection as resolveBackendWorldSelection,
8
8
  } from '../../product-shell/contracts/world-orchestration.js';
9
9
 
@@ -203,12 +203,6 @@ function normalizeWorldDetail(payload = {}) {
203
203
  };
204
204
  }
205
205
 
206
- function normalizeNumber(value, fallback = null) {
207
- const parsed = Number(value);
208
- if (!Number.isFinite(parsed)) return fallback;
209
- return parsed;
210
- }
211
-
212
206
  function normalizeProfileSummaryField(field = {}, index = 0) {
213
207
  const fieldId = normalizeText(field.fieldId || field.id, `field_${index + 1}`);
214
208
  const value = Array.isArray(field.value)
@@ -226,7 +220,7 @@ function normalizeProfileSummaryField(field = {}, index = 0) {
226
220
  };
227
221
  }
228
222
 
229
- function normalizeCandidateProfileSummary(summary = {}) {
223
+ function normalizeMemberProfileSummary(summary = {}) {
230
224
  return {
231
225
  displayName: normalizeText(summary.displayName, null),
232
226
  headline: normalizeText(summary.headline, null),
@@ -265,102 +259,6 @@ function normalizeBroadcastConfig(broadcast = null) {
265
259
  };
266
260
  }
267
261
 
268
- function normalizeCompatibilitySignal(signal = {}, index = 0) {
269
- return {
270
- signalId: normalizeText(signal.signalId, `signal_${index + 1}`),
271
- type: normalizeText(signal.type, 'world_ready'),
272
- fieldIds: normalizeStringList(signal.fieldIds),
273
- score: normalizeNumber(signal.score, 0),
274
- summary: normalizeText(signal.summary, ''),
275
- };
276
- }
277
-
278
- function normalizeDeliveryReason(reason = {}) {
279
- return {
280
- code: normalizeText(reason.code, null),
281
- matchedFieldIds: normalizeStringList(reason.matchedFieldIds),
282
- summary: normalizeText(reason.summary, ''),
283
- };
284
- }
285
-
286
- function normalizeCandidate(candidate = {}, index = 0) {
287
- const normalizedRank = normalizeNumber(candidate.rank, null);
288
- const displayName = normalizeText(
289
- candidate.displayName || candidate.profileSummary?.displayName || candidate.requestChat?.displayName,
290
- null,
291
- );
292
- const agentCode = normalizeText(
293
- candidate.agentCode || candidate.requestChat?.agentCode,
294
- null,
295
- )?.toUpperCase() || null;
296
- const requestChat = displayName && agentCode
297
- ? {
298
- worldId: normalizeText(candidate.requestChat?.worldId, normalizeText(candidate.worldId, 'unknown-world')),
299
- displayName,
300
- agentCode,
301
- }
302
- : null;
303
-
304
- return {
305
- candidateId: normalizeText(candidate.candidateId, `candidate_${index + 1}`),
306
- worldId: normalizeText(candidate.worldId, 'unknown-world'),
307
- worldRole: normalizeWorldRole(candidate.worldRole, null),
308
- sourceMembershipId: normalizeText(candidate.sourceMembershipId, null),
309
- online: candidate.online === true,
310
- displayName,
311
- agentCode,
312
- requestChat,
313
- profileSummary: normalizeCandidateProfileSummary(candidate.profileSummary),
314
- compatibilitySignals: Array.isArray(candidate.compatibilitySignals)
315
- ? candidate.compatibilitySignals.map((signal, signalIndex) => normalizeCompatibilitySignal(signal, signalIndex))
316
- : [],
317
- deliveryReason: normalizeDeliveryReason(candidate.deliveryReason),
318
- worldFeedbackSummary: candidate.worldFeedbackSummary && typeof candidate.worldFeedbackSummary === 'object'
319
- ? {
320
- likesReceived: normalizeInteger(candidate.worldFeedbackSummary.likesReceived, 0),
321
- dislikesReceived: normalizeInteger(candidate.worldFeedbackSummary.dislikesReceived, 0),
322
- }
323
- : {
324
- likesReceived: 0,
325
- dislikesReceived: 0,
326
- },
327
- expiresAt: normalizeText(candidate.expiresAt, null),
328
- joinedAt: normalizeText(candidate.joinedAt, null),
329
- rank: normalizedRank == null ? null : Math.max(1, Math.trunc(normalizedRank)),
330
- score: normalizeNumber(candidate.score, null),
331
- };
332
- }
333
-
334
- function normalizeCandidateFeedResponse(payload = {}, { worldId = null, agentId = null } = {}) {
335
- const candidates = Array.isArray(payload.candidates)
336
- ? payload.candidates.map((candidate, index) => normalizeCandidate(candidate, index))
337
- : [];
338
-
339
- return {
340
- worldId: normalizeText(payload.worldId, worldId || 'unknown-world'),
341
- agentId: normalizeText(payload.agentId, agentId || null),
342
- viewerMembershipId: normalizeText(payload.viewerMembershipId, null),
343
- generatedAt: normalizeText(payload.generatedAt, null),
344
- expiresAt: normalizeText(payload.expiresAt, null),
345
- deliveryMode: normalizeText(payload.deliveryMode, 'agent_review_before_live_session'),
346
- nextAction: normalizeText(
347
- payload.nextAction,
348
- candidates.length > 0 ? 'review_candidates_then_request_chat' : 'wait_for_more_candidates',
349
- ),
350
- candidateDelivery: payload.candidateDelivery && typeof payload.candidateDelivery === 'object'
351
- ? payload.candidateDelivery
352
- : null,
353
- candidateSource: normalizeText(payload.candidateSource, 'active_memberships_online'),
354
- candidateModel: payload.candidateModel && typeof payload.candidateModel === 'object' ? payload.candidateModel : {},
355
- strategy: payload.strategy && typeof payload.strategy === 'object' ? payload.strategy : {},
356
- limit: normalizeInteger(payload.limit, candidates.length),
357
- totalCandidates: normalizeInteger(payload.totalCandidates, candidates.length),
358
- status: normalizeText(payload.status, candidates.length > 0 ? 'feed_ready' : 'no_candidates_ready'),
359
- candidates,
360
- };
361
- }
362
-
363
-
364
262
  function normalizeActionPayload(value = null) {
365
263
  return value && typeof value === 'object' && !Array.isArray(value) ? value : null;
366
264
  }
@@ -413,20 +311,6 @@ function summarizeProfileFields(fields = []) {
413
311
  .filter(Boolean);
414
312
  }
415
313
 
416
- function buildCandidateDeliverySummaryLine(candidateSummary = {}, index = 0) {
417
- return `${index + 1}. ${candidateSummary.summary}`;
418
- }
419
-
420
- export function buildCandidateDeliverySummary(candidateFeed = {}, { worldDetail = null, limit = null } = {}) {
421
- if (candidateFeed?.candidateDelivery && typeof candidateFeed.candidateDelivery === 'object') {
422
- return candidateFeed.candidateDelivery;
423
- }
424
- if (worldDetail?.candidateDelivery && typeof worldDetail.candidateDelivery === 'object') {
425
- return worldDetail.candidateDelivery;
426
- }
427
- return buildBackendCandidateDeliverySummary(candidateFeed, { worldDetail, limit });
428
- }
429
-
430
314
  export function buildWorldSelectionPrompt(worldDirectory = {}) {
431
315
  return worldDirectory?.orchestration && typeof worldDirectory.orchestration === 'object'
432
316
  ? worldDirectory.orchestration
@@ -476,7 +360,10 @@ export function buildPostSetupWorldDirectory(payload = {}, {
476
360
  nextAction: normalizeText(payload.nextAction, items.length > 0 ? 'inspect_world_detail_or_join_world' : 'broaden_world_search'),
477
361
  orchestration: payload.orchestration && typeof payload.orchestration === 'object'
478
362
  ? payload.orchestration
479
- : null,
363
+ : buildBackendWorldSelectionPrompt({
364
+ items,
365
+ recommendedWorldId,
366
+ }),
480
367
  };
481
368
  }
482
369
 
@@ -495,7 +382,7 @@ function normalizeWorldMemberSearchItem(item = {}) {
495
382
  matchedFieldIds: normalizeStringList(item.matchedFieldIds),
496
383
  reasonSummary: normalizeText(item.reasonSummary, null),
497
384
  joinedAt: normalizeText(item.joinedAt, null),
498
- profileSummary: normalizeCandidateProfileSummary(item.profileSummary || {}),
385
+ profileSummary: normalizeMemberProfileSummary(item.profileSummary || {}),
499
386
  worldFeedbackSummary: item.worldFeedbackSummary && typeof item.worldFeedbackSummary === 'object' && !Array.isArray(item.worldFeedbackSummary)
500
387
  ? {
501
388
  likesReceived: normalizeInteger(item.worldFeedbackSummary.likesReceived, 0),
@@ -519,10 +406,10 @@ export function normalizeWorldMemberSearchResponse(payload = {}, { accountId = n
519
406
  accountId: normalizeText(accountId, null),
520
407
  worldId: normalizeText(payload.worldId, null),
521
408
  query: normalizeText(payload.query, null),
522
- sort: normalizeText(payload.sort, 'match'),
409
+ sort: normalizeText(payload.sort, 'relevance'),
523
410
  limit: normalizeInteger(payload.limit, items.length),
524
411
  totalMatches: normalizeInteger(payload.totalMatches, items.length),
525
- nextAction: normalizeText(payload.nextAction, items.length > 0 ? 'request_chat_with_selected_candidate' : 'broaden_search_or_refresh_candidate_feed'),
412
+ nextAction: normalizeText(payload.nextAction, items.length > 0 ? 'request_chat_with_selected_result' : 'broaden_search'),
526
413
  items,
527
414
  };
528
415
  }
@@ -647,6 +534,13 @@ export async function searchWorlds({
647
534
  accountId = null,
648
535
  runtimeConfig = null,
649
536
  query = null,
537
+ keywords = [],
538
+ topics = [],
539
+ location = null,
540
+ timeWindow = null,
541
+ intent = null,
542
+ desiredInteraction = null,
543
+ constraints = [],
650
544
  limit = null,
651
545
  sort = null,
652
546
  page = null,
@@ -668,6 +562,13 @@ export async function searchWorlds({
668
562
  }),
669
563
  body: JSON.stringify({
670
564
  query: normalizeText(query, null),
565
+ keywords: normalizeStringList(keywords),
566
+ topics: normalizeStringList(topics),
567
+ location: normalizeText(location, null),
568
+ timeWindow: normalizeText(timeWindow, null),
569
+ intent: normalizeText(intent, null),
570
+ desiredInteraction: normalizeText(desiredInteraction, null),
571
+ constraints: normalizeStringList(constraints),
671
572
  sort: normalizeText(sort, null),
672
573
  limit: limit == null ? null : normalizeInteger(limit, 0),
673
574
  page: page == null ? null : normalizeInteger(page, 0),
@@ -699,6 +600,13 @@ export async function search({
699
600
  worldId = null,
700
601
  agentId = null,
701
602
  query = null,
603
+ keywords = [],
604
+ topics = [],
605
+ location = null,
606
+ timeWindow = null,
607
+ intent = null,
608
+ desiredInteraction = null,
609
+ constraints = [],
702
610
  limit = null,
703
611
  sort = null,
704
612
  page = null,
@@ -723,6 +631,13 @@ export async function search({
723
631
  worldId: normalizeText(worldId, null),
724
632
  agentId: normalizeText(agentId, null),
725
633
  query: normalizeText(query, null),
634
+ keywords: normalizeStringList(keywords),
635
+ topics: normalizeStringList(topics),
636
+ location: normalizeText(location, null),
637
+ timeWindow: normalizeText(timeWindow, null),
638
+ intent: normalizeText(intent, null),
639
+ desiredInteraction: normalizeText(desiredInteraction, null),
640
+ constraints: normalizeStringList(constraints),
726
641
  sort: normalizeText(sort, null),
727
642
  limit: limit == null ? null : normalizeInteger(limit, 0),
728
643
  page: page == null ? null : normalizeInteger(page, 0),
@@ -749,94 +664,122 @@ export async function search({
749
664
  };
750
665
  }
751
666
 
752
- export async function joinWorld({
667
+ export async function getPublicProfile({
753
668
  cfg = {},
754
669
  accountId = null,
755
670
  runtimeConfig = null,
756
- worldId = null,
757
671
  agentId = null,
758
- participantContextText = null,
672
+ viewerAgentId = null,
759
673
  fetchImpl,
760
674
  logger = console,
761
675
  } = {}) {
762
676
  if (typeof fetchImpl !== 'function') {
763
- throw new Error('fetch is unavailable for claworld product-shell join helper');
677
+ throw new Error('fetch is unavailable for claworld public-profile helper');
764
678
  }
765
-
766
- const resolvedWorldId = normalizeText(worldId, null);
767
- if (!resolvedWorldId) {
768
- throw new Error('claworld product-shell join helper requires worldId');
769
- }
770
-
771
679
  const resolvedAgentId = normalizeText(agentId, null);
772
680
  if (!resolvedAgentId) {
773
- throw new Error('claworld product-shell join helper requires agentId');
681
+ throw new Error('claworld public-profile helper requires agentId');
774
682
  }
775
-
776
683
  const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
777
684
  const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
778
- const joinResult = await fetchJson(fetchImpl, `${baseUrl}/v1/worlds/${encodeURIComponent(resolvedWorldId)}/join`, {
779
- method: 'POST',
685
+ const requestUrl = new URL(`${baseUrl}/v1/public-profiles/${encodeURIComponent(resolvedAgentId)}`);
686
+ const resolvedViewerAgentId = normalizeText(viewerAgentId, null);
687
+ if (resolvedViewerAgentId) requestUrl.searchParams.set('viewerAgentId', resolvedViewerAgentId);
688
+ const profileResult = await fetchJson(fetchImpl, requestUrl.toString(), {
780
689
  headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
781
690
  accept: 'application/json',
782
- 'content-type': 'application/json',
783
691
  ...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
784
692
  }),
785
- body: JSON.stringify({
786
- agentId: resolvedAgentId,
787
- participantContextText: normalizeText(participantContextText, null),
788
- }),
789
693
  });
790
-
791
- if (!joinResult.ok) {
792
- logger.error?.('[claworld:product-shell] world join failed', {
793
- status: joinResult.status,
794
- worldId: resolvedWorldId,
795
- agentId: resolvedAgentId,
694
+ if (!profileResult.ok) {
695
+ logger.error?.('[claworld:product-shell] public profile fetch failed', {
696
+ status: profileResult.status,
796
697
  accountId: resolvedRuntimeConfig.accountId || accountId || null,
797
- body: joinResult.body,
698
+ agentId: resolvedAgentId,
699
+ body: profileResult.body,
798
700
  });
799
- throw createProductShellHttpError('world_join', joinResult, {
701
+ throw createProductShellHttpError('public_profile', profileResult, {
800
702
  accountId: resolvedRuntimeConfig.accountId || accountId || null,
801
- worldId: resolvedWorldId,
802
703
  });
803
704
  }
705
+ return {
706
+ accountId: resolvedRuntimeConfig.accountId || accountId || null,
707
+ ...profileResult.body,
708
+ };
709
+ }
804
710
 
805
- return normalizeWorldJoinResponse(joinResult.body, {
806
- worldId: resolvedWorldId,
807
- agentId: resolvedAgentId,
711
+ export async function lookupPublicProfile({
712
+ cfg = {},
713
+ accountId = null,
714
+ runtimeConfig = null,
715
+ identity = null,
716
+ viewerAgentId = null,
717
+ fetchImpl,
718
+ logger = console,
719
+ } = {}) {
720
+ if (typeof fetchImpl !== 'function') {
721
+ throw new Error('fetch is unavailable for claworld public-profile helper');
722
+ }
723
+ const resolvedIdentity = normalizeText(identity, null);
724
+ if (!resolvedIdentity) {
725
+ throw new Error('claworld public-profile lookup helper requires identity');
726
+ }
727
+ const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
728
+ const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
729
+ const requestUrl = new URL(`${baseUrl}/v1/public-profiles/lookup`);
730
+ requestUrl.searchParams.set('identity', resolvedIdentity);
731
+ const resolvedViewerAgentId = normalizeText(viewerAgentId, null);
732
+ if (resolvedViewerAgentId) requestUrl.searchParams.set('viewerAgentId', resolvedViewerAgentId);
733
+ const profileResult = await fetchJson(fetchImpl, requestUrl.toString(), {
734
+ headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
735
+ accept: 'application/json',
736
+ ...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
737
+ }),
808
738
  });
739
+ if (!profileResult.ok) {
740
+ logger.error?.('[claworld:product-shell] public profile lookup failed', {
741
+ status: profileResult.status,
742
+ accountId: resolvedRuntimeConfig.accountId || accountId || null,
743
+ identity: resolvedIdentity,
744
+ body: profileResult.body,
745
+ });
746
+ throw createProductShellHttpError('public_profile_lookup', profileResult, {
747
+ accountId: resolvedRuntimeConfig.accountId || accountId || null,
748
+ });
749
+ }
750
+ return {
751
+ accountId: resolvedRuntimeConfig.accountId || accountId || null,
752
+ ...profileResult.body,
753
+ };
809
754
  }
810
755
 
811
- export async function searchWorldMembers({
756
+ export async function joinWorld({
812
757
  cfg = {},
813
758
  accountId = null,
814
759
  runtimeConfig = null,
815
760
  worldId = null,
816
761
  agentId = null,
817
- query = null,
818
- sort = null,
819
- limit = null,
762
+ participantContextText = null,
820
763
  fetchImpl,
821
764
  logger = console,
822
765
  } = {}) {
823
766
  if (typeof fetchImpl !== 'function') {
824
- throw new Error('fetch is unavailable for claworld product-shell member search helper');
767
+ throw new Error('fetch is unavailable for claworld product-shell join helper');
825
768
  }
826
769
 
827
770
  const resolvedWorldId = normalizeText(worldId, null);
828
771
  if (!resolvedWorldId) {
829
- throw new Error('claworld product-shell member search helper requires worldId');
772
+ throw new Error('claworld product-shell join helper requires worldId');
830
773
  }
831
774
 
832
775
  const resolvedAgentId = normalizeText(agentId, null);
833
776
  if (!resolvedAgentId) {
834
- throw new Error('claworld product-shell member search helper requires agentId');
777
+ throw new Error('claworld product-shell join helper requires agentId');
835
778
  }
836
779
 
837
780
  const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
838
781
  const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
839
- const searchResult = await fetchJson(fetchImpl, `${baseUrl}/v1/worlds/${encodeURIComponent(resolvedWorldId)}/search`, {
782
+ const joinResult = await fetchJson(fetchImpl, `${baseUrl}/v1/worlds/${encodeURIComponent(resolvedWorldId)}/join`, {
840
783
  method: 'POST',
841
784
  headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
842
785
  accept: 'application/json',
@@ -845,58 +788,65 @@ export async function searchWorldMembers({
845
788
  }),
846
789
  body: JSON.stringify({
847
790
  agentId: resolvedAgentId,
848
- query: normalizeText(query, null),
849
- sort: normalizeText(sort, null),
850
- limit: limit == null ? null : normalizeInteger(limit, 0),
791
+ participantContextText: normalizeText(participantContextText, null),
851
792
  }),
852
793
  });
853
794
 
854
- if (!searchResult.ok) {
855
- logger.error?.('[claworld:product-shell] world member search failed', {
856
- status: searchResult.status,
795
+ if (!joinResult.ok) {
796
+ logger.error?.('[claworld:product-shell] world join failed', {
797
+ status: joinResult.status,
857
798
  worldId: resolvedWorldId,
858
799
  agentId: resolvedAgentId,
859
800
  accountId: resolvedRuntimeConfig.accountId || accountId || null,
860
- body: searchResult.body,
801
+ body: joinResult.body,
861
802
  });
862
- throw createProductShellHttpError('world_member_search', searchResult, {
803
+ throw createProductShellHttpError('world_join', joinResult, {
863
804
  accountId: resolvedRuntimeConfig.accountId || accountId || null,
864
805
  worldId: resolvedWorldId,
865
806
  });
866
807
  }
867
808
 
868
- return normalizeWorldMemberSearchResponse(searchResult.body, {
869
- accountId: resolvedRuntimeConfig.accountId || accountId || null,
809
+ return normalizeWorldJoinResponse(joinResult.body, {
810
+ worldId: resolvedWorldId,
811
+ agentId: resolvedAgentId,
870
812
  });
871
813
  }
872
814
 
873
- export async function fetchWorldCandidateFeed({
815
+ export async function searchWorldMembers({
874
816
  cfg = {},
875
817
  accountId = null,
876
818
  runtimeConfig = null,
877
819
  worldId = null,
878
820
  agentId = null,
821
+ query = null,
822
+ keywords = [],
823
+ topics = [],
824
+ location = null,
825
+ timeWindow = null,
826
+ intent = null,
827
+ desiredInteraction = null,
828
+ constraints = [],
829
+ sort = null,
879
830
  limit = null,
880
831
  fetchImpl,
881
832
  logger = console,
882
833
  } = {}) {
883
834
  if (typeof fetchImpl !== 'function') {
884
- throw new Error('fetch is unavailable for claworld product-shell candidate feed helper');
835
+ throw new Error('fetch is unavailable for claworld product-shell member search helper');
885
836
  }
886
837
 
887
838
  const resolvedWorldId = normalizeText(worldId, null);
888
839
  if (!resolvedWorldId) {
889
- throw new Error('claworld product-shell candidate feed helper requires worldId');
840
+ throw new Error('claworld product-shell member search helper requires worldId');
890
841
  }
891
842
 
892
843
  const resolvedAgentId = normalizeText(agentId, null);
893
844
  if (!resolvedAgentId) {
894
- throw new Error('claworld product-shell candidate feed helper requires agentId');
845
+ throw new Error('claworld product-shell member search helper requires agentId');
895
846
  }
896
847
 
897
848
  const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
898
849
  const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
899
- const normalizedLimit = normalizeInteger(limit, 0);
900
850
  const searchResult = await fetchJson(fetchImpl, `${baseUrl}/v1/worlds/${encodeURIComponent(resolvedWorldId)}/search`, {
901
851
  method: 'POST',
902
852
  headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
@@ -906,60 +856,36 @@ export async function fetchWorldCandidateFeed({
906
856
  }),
907
857
  body: JSON.stringify({
908
858
  agentId: resolvedAgentId,
909
- query: null,
910
- sort: 'match',
911
- limit: normalizedLimit > 0 ? normalizedLimit : null,
859
+ query: normalizeText(query, null),
860
+ keywords: normalizeStringList(keywords),
861
+ topics: normalizeStringList(topics),
862
+ location: normalizeText(location, null),
863
+ timeWindow: normalizeText(timeWindow, null),
864
+ intent: normalizeText(intent, null),
865
+ desiredInteraction: normalizeText(desiredInteraction, null),
866
+ constraints: normalizeStringList(constraints),
867
+ sort: normalizeText(sort, null),
868
+ limit: limit == null ? null : normalizeInteger(limit, 0),
912
869
  }),
913
870
  });
914
871
 
915
872
  if (!searchResult.ok) {
916
- logger.error?.('[claworld:product-shell] candidate feed compatibility search failed', {
873
+ logger.error?.('[claworld:product-shell] world member search failed', {
917
874
  status: searchResult.status,
918
875
  worldId: resolvedWorldId,
919
876
  agentId: resolvedAgentId,
920
877
  accountId: resolvedRuntimeConfig.accountId || accountId || null,
921
878
  body: searchResult.body,
922
879
  });
923
- throw createProductShellHttpError('world_candidate_feed', searchResult, {
880
+ throw createProductShellHttpError('world_member_search', searchResult, {
924
881
  accountId: resolvedRuntimeConfig.accountId || accountId || null,
925
882
  worldId: resolvedWorldId,
926
883
  });
927
884
  }
928
885
 
929
- const searchPayload = searchResult.body && typeof searchResult.body === 'object' ? searchResult.body : {};
930
- const normalizedSearch = normalizeWorldMemberSearchResponse(searchPayload, {
886
+ return normalizeWorldMemberSearchResponse(searchResult.body, {
931
887
  accountId: resolvedRuntimeConfig.accountId || accountId || null,
932
888
  });
933
- return normalizeCandidateFeedResponse({
934
- worldId: resolvedWorldId,
935
- agentId: resolvedAgentId,
936
- viewerMembershipId: searchPayload.viewerMembershipId,
937
- generatedAt: searchPayload.generatedAt,
938
- limit: normalizedSearch.limit,
939
- totalCandidates: normalizedSearch.totalMatches,
940
- candidateSource: searchPayload.candidateSource || 'active_memberships',
941
- status: normalizedSearch.items.length > 0 ? 'feed_ready' : 'no_candidates_ready',
942
- nextAction: normalizedSearch.nextAction,
943
- candidates: normalizedSearch.items.map((item, index) => ({
944
- candidateId: item.membershipId || `candidate_${index + 1}`,
945
- sourceMembershipId: item.membershipId || null,
946
- worldId: item.worldId || resolvedWorldId,
947
- online: item.online === true,
948
- rank: index + 1,
949
- score: item.score,
950
- agentCode: item.agentCode,
951
- requestChat: item.requestChat,
952
- profileSummary: item.profileSummary,
953
- deliveryReason: {
954
- summary: item.reasonSummary || item.headline || null,
955
- },
956
- worldFeedbackSummary: item.worldFeedbackSummary,
957
- joinedAt: item.joinedAt,
958
- })),
959
- }, {
960
- worldId: resolvedWorldId,
961
- agentId: resolvedAgentId,
962
- });
963
889
  }
964
890
 
965
891
  export async function resolveWorldSelectionFlow({