@xfxstudio/claworld 2026.4.27-testing.1 → 2026.4.28-testing
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.
- package/openclaw.plugin.json +245 -234
- package/package.json +1 -1
- package/skills/claworld-help/SKILL.md +3 -3
- package/src/openclaw/index.js +3 -0
- package/src/openclaw/plugin/claworld-channel-plugin.js +30 -90
- package/src/openclaw/plugin/config-schema.js +6 -0
- package/src/openclaw/plugin/register-tooling.js +0 -4
- package/src/openclaw/plugin/register.js +394 -118
- package/src/openclaw/runtime/feedback-helper.js +2 -2
- package/src/openclaw/runtime/product-shell-helper.js +213 -139
- package/src/openclaw/runtime/tool-contracts.js +195 -6
- package/src/openclaw/runtime/tool-inventory.js +15 -0
- package/src/openclaw/runtime/working-memory.js +2 -0
- package/src/openclaw/runtime/world-moderation-helper.js +0 -16
- package/src/product-shell/contracts/world-orchestration.js +270 -1
|
@@ -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
|
-
|
|
6
|
+
buildCandidateDeliverySummary as buildBackendCandidateDeliverySummary,
|
|
7
7
|
resolveWorldSelection as resolveBackendWorldSelection,
|
|
8
8
|
} from '../../product-shell/contracts/world-orchestration.js';
|
|
9
9
|
|
|
@@ -203,6 +203,12 @@ 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
|
+
|
|
206
212
|
function normalizeProfileSummaryField(field = {}, index = 0) {
|
|
207
213
|
const fieldId = normalizeText(field.fieldId || field.id, `field_${index + 1}`);
|
|
208
214
|
const value = Array.isArray(field.value)
|
|
@@ -220,7 +226,7 @@ function normalizeProfileSummaryField(field = {}, index = 0) {
|
|
|
220
226
|
};
|
|
221
227
|
}
|
|
222
228
|
|
|
223
|
-
function
|
|
229
|
+
function normalizeCandidateProfileSummary(summary = {}) {
|
|
224
230
|
return {
|
|
225
231
|
displayName: normalizeText(summary.displayName, null),
|
|
226
232
|
headline: normalizeText(summary.headline, null),
|
|
@@ -259,6 +265,102 @@ function normalizeBroadcastConfig(broadcast = null) {
|
|
|
259
265
|
};
|
|
260
266
|
}
|
|
261
267
|
|
|
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
|
+
|
|
262
364
|
function normalizeActionPayload(value = null) {
|
|
263
365
|
return value && typeof value === 'object' && !Array.isArray(value) ? value : null;
|
|
264
366
|
}
|
|
@@ -311,6 +413,20 @@ function summarizeProfileFields(fields = []) {
|
|
|
311
413
|
.filter(Boolean);
|
|
312
414
|
}
|
|
313
415
|
|
|
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
|
+
|
|
314
430
|
export function buildWorldSelectionPrompt(worldDirectory = {}) {
|
|
315
431
|
return worldDirectory?.orchestration && typeof worldDirectory.orchestration === 'object'
|
|
316
432
|
? worldDirectory.orchestration
|
|
@@ -360,10 +476,7 @@ export function buildPostSetupWorldDirectory(payload = {}, {
|
|
|
360
476
|
nextAction: normalizeText(payload.nextAction, items.length > 0 ? 'inspect_world_detail_or_join_world' : 'broaden_world_search'),
|
|
361
477
|
orchestration: payload.orchestration && typeof payload.orchestration === 'object'
|
|
362
478
|
? payload.orchestration
|
|
363
|
-
:
|
|
364
|
-
items,
|
|
365
|
-
recommendedWorldId,
|
|
366
|
-
}),
|
|
479
|
+
: null,
|
|
367
480
|
};
|
|
368
481
|
}
|
|
369
482
|
|
|
@@ -382,7 +495,7 @@ function normalizeWorldMemberSearchItem(item = {}) {
|
|
|
382
495
|
matchedFieldIds: normalizeStringList(item.matchedFieldIds),
|
|
383
496
|
reasonSummary: normalizeText(item.reasonSummary, null),
|
|
384
497
|
joinedAt: normalizeText(item.joinedAt, null),
|
|
385
|
-
profileSummary:
|
|
498
|
+
profileSummary: normalizeCandidateProfileSummary(item.profileSummary || {}),
|
|
386
499
|
worldFeedbackSummary: item.worldFeedbackSummary && typeof item.worldFeedbackSummary === 'object' && !Array.isArray(item.worldFeedbackSummary)
|
|
387
500
|
? {
|
|
388
501
|
likesReceived: normalizeInteger(item.worldFeedbackSummary.likesReceived, 0),
|
|
@@ -406,10 +519,10 @@ export function normalizeWorldMemberSearchResponse(payload = {}, { accountId = n
|
|
|
406
519
|
accountId: normalizeText(accountId, null),
|
|
407
520
|
worldId: normalizeText(payload.worldId, null),
|
|
408
521
|
query: normalizeText(payload.query, null),
|
|
409
|
-
sort: normalizeText(payload.sort, '
|
|
522
|
+
sort: normalizeText(payload.sort, 'match'),
|
|
410
523
|
limit: normalizeInteger(payload.limit, items.length),
|
|
411
524
|
totalMatches: normalizeInteger(payload.totalMatches, items.length),
|
|
412
|
-
nextAction: normalizeText(payload.nextAction, items.length > 0 ? '
|
|
525
|
+
nextAction: normalizeText(payload.nextAction, items.length > 0 ? 'request_chat_with_selected_candidate' : 'broaden_search_or_refresh_candidate_feed'),
|
|
413
526
|
items,
|
|
414
527
|
};
|
|
415
528
|
}
|
|
@@ -534,13 +647,6 @@ export async function searchWorlds({
|
|
|
534
647
|
accountId = null,
|
|
535
648
|
runtimeConfig = null,
|
|
536
649
|
query = null,
|
|
537
|
-
keywords = [],
|
|
538
|
-
topics = [],
|
|
539
|
-
location = null,
|
|
540
|
-
timeWindow = null,
|
|
541
|
-
intent = null,
|
|
542
|
-
desiredInteraction = null,
|
|
543
|
-
constraints = [],
|
|
544
650
|
limit = null,
|
|
545
651
|
sort = null,
|
|
546
652
|
page = null,
|
|
@@ -562,13 +668,6 @@ export async function searchWorlds({
|
|
|
562
668
|
}),
|
|
563
669
|
body: JSON.stringify({
|
|
564
670
|
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),
|
|
572
671
|
sort: normalizeText(sort, null),
|
|
573
672
|
limit: limit == null ? null : normalizeInteger(limit, 0),
|
|
574
673
|
page: page == null ? null : normalizeInteger(page, 0),
|
|
@@ -600,13 +699,6 @@ export async function search({
|
|
|
600
699
|
worldId = null,
|
|
601
700
|
agentId = null,
|
|
602
701
|
query = null,
|
|
603
|
-
keywords = [],
|
|
604
|
-
topics = [],
|
|
605
|
-
location = null,
|
|
606
|
-
timeWindow = null,
|
|
607
|
-
intent = null,
|
|
608
|
-
desiredInteraction = null,
|
|
609
|
-
constraints = [],
|
|
610
702
|
limit = null,
|
|
611
703
|
sort = null,
|
|
612
704
|
page = null,
|
|
@@ -631,13 +723,6 @@ export async function search({
|
|
|
631
723
|
worldId: normalizeText(worldId, null),
|
|
632
724
|
agentId: normalizeText(agentId, null),
|
|
633
725
|
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),
|
|
641
726
|
sort: normalizeText(sort, null),
|
|
642
727
|
limit: limit == null ? null : normalizeInteger(limit, 0),
|
|
643
728
|
page: page == null ? null : normalizeInteger(page, 0),
|
|
@@ -664,122 +749,94 @@ export async function search({
|
|
|
664
749
|
};
|
|
665
750
|
}
|
|
666
751
|
|
|
667
|
-
export async function
|
|
752
|
+
export async function joinWorld({
|
|
668
753
|
cfg = {},
|
|
669
754
|
accountId = null,
|
|
670
755
|
runtimeConfig = null,
|
|
756
|
+
worldId = null,
|
|
671
757
|
agentId = null,
|
|
672
|
-
|
|
758
|
+
participantContextText = null,
|
|
673
759
|
fetchImpl,
|
|
674
760
|
logger = console,
|
|
675
761
|
} = {}) {
|
|
676
762
|
if (typeof fetchImpl !== 'function') {
|
|
677
|
-
throw new Error('fetch is unavailable for claworld
|
|
763
|
+
throw new Error('fetch is unavailable for claworld product-shell join helper');
|
|
678
764
|
}
|
|
765
|
+
|
|
766
|
+
const resolvedWorldId = normalizeText(worldId, null);
|
|
767
|
+
if (!resolvedWorldId) {
|
|
768
|
+
throw new Error('claworld product-shell join helper requires worldId');
|
|
769
|
+
}
|
|
770
|
+
|
|
679
771
|
const resolvedAgentId = normalizeText(agentId, null);
|
|
680
772
|
if (!resolvedAgentId) {
|
|
681
|
-
throw new Error('claworld
|
|
773
|
+
throw new Error('claworld product-shell join helper requires agentId');
|
|
682
774
|
}
|
|
775
|
+
|
|
683
776
|
const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
|
|
684
777
|
const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
|
|
685
|
-
const
|
|
686
|
-
|
|
687
|
-
if (resolvedViewerAgentId) requestUrl.searchParams.set('viewerAgentId', resolvedViewerAgentId);
|
|
688
|
-
const profileResult = await fetchJson(fetchImpl, requestUrl.toString(), {
|
|
778
|
+
const joinResult = await fetchJson(fetchImpl, `${baseUrl}/v1/worlds/${encodeURIComponent(resolvedWorldId)}/join`, {
|
|
779
|
+
method: 'POST',
|
|
689
780
|
headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
|
|
690
781
|
accept: 'application/json',
|
|
782
|
+
'content-type': 'application/json',
|
|
691
783
|
...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
|
|
692
784
|
}),
|
|
693
|
-
|
|
694
|
-
if (!profileResult.ok) {
|
|
695
|
-
logger.error?.('[claworld:product-shell] public profile fetch failed', {
|
|
696
|
-
status: profileResult.status,
|
|
697
|
-
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
785
|
+
body: JSON.stringify({
|
|
698
786
|
agentId: resolvedAgentId,
|
|
699
|
-
|
|
700
|
-
});
|
|
701
|
-
throw createProductShellHttpError('public_profile', profileResult, {
|
|
702
|
-
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
703
|
-
});
|
|
704
|
-
}
|
|
705
|
-
return {
|
|
706
|
-
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
707
|
-
...profileResult.body,
|
|
708
|
-
};
|
|
709
|
-
}
|
|
710
|
-
|
|
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 } : {}),
|
|
787
|
+
participantContextText: normalizeText(participantContextText, null),
|
|
737
788
|
}),
|
|
738
789
|
});
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
790
|
+
|
|
791
|
+
if (!joinResult.ok) {
|
|
792
|
+
logger.error?.('[claworld:product-shell] world join failed', {
|
|
793
|
+
status: joinResult.status,
|
|
794
|
+
worldId: resolvedWorldId,
|
|
795
|
+
agentId: resolvedAgentId,
|
|
742
796
|
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
743
|
-
|
|
744
|
-
body: profileResult.body,
|
|
797
|
+
body: joinResult.body,
|
|
745
798
|
});
|
|
746
|
-
throw createProductShellHttpError('
|
|
799
|
+
throw createProductShellHttpError('world_join', joinResult, {
|
|
747
800
|
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
801
|
+
worldId: resolvedWorldId,
|
|
748
802
|
});
|
|
749
803
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
804
|
+
|
|
805
|
+
return normalizeWorldJoinResponse(joinResult.body, {
|
|
806
|
+
worldId: resolvedWorldId,
|
|
807
|
+
agentId: resolvedAgentId,
|
|
808
|
+
});
|
|
754
809
|
}
|
|
755
810
|
|
|
756
|
-
export async function
|
|
811
|
+
export async function searchWorldMembers({
|
|
757
812
|
cfg = {},
|
|
758
813
|
accountId = null,
|
|
759
814
|
runtimeConfig = null,
|
|
760
815
|
worldId = null,
|
|
761
816
|
agentId = null,
|
|
762
|
-
|
|
817
|
+
query = null,
|
|
818
|
+
sort = null,
|
|
819
|
+
limit = null,
|
|
763
820
|
fetchImpl,
|
|
764
821
|
logger = console,
|
|
765
822
|
} = {}) {
|
|
766
823
|
if (typeof fetchImpl !== 'function') {
|
|
767
|
-
throw new Error('fetch is unavailable for claworld product-shell
|
|
824
|
+
throw new Error('fetch is unavailable for claworld product-shell member search helper');
|
|
768
825
|
}
|
|
769
826
|
|
|
770
827
|
const resolvedWorldId = normalizeText(worldId, null);
|
|
771
828
|
if (!resolvedWorldId) {
|
|
772
|
-
throw new Error('claworld product-shell
|
|
829
|
+
throw new Error('claworld product-shell member search helper requires worldId');
|
|
773
830
|
}
|
|
774
831
|
|
|
775
832
|
const resolvedAgentId = normalizeText(agentId, null);
|
|
776
833
|
if (!resolvedAgentId) {
|
|
777
|
-
throw new Error('claworld product-shell
|
|
834
|
+
throw new Error('claworld product-shell member search helper requires agentId');
|
|
778
835
|
}
|
|
779
836
|
|
|
780
837
|
const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
|
|
781
838
|
const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
|
|
782
|
-
const
|
|
839
|
+
const searchResult = await fetchJson(fetchImpl, `${baseUrl}/v1/worlds/${encodeURIComponent(resolvedWorldId)}/search`, {
|
|
783
840
|
method: 'POST',
|
|
784
841
|
headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
|
|
785
842
|
accept: 'application/json',
|
|
@@ -788,65 +845,58 @@ export async function joinWorld({
|
|
|
788
845
|
}),
|
|
789
846
|
body: JSON.stringify({
|
|
790
847
|
agentId: resolvedAgentId,
|
|
791
|
-
|
|
848
|
+
query: normalizeText(query, null),
|
|
849
|
+
sort: normalizeText(sort, null),
|
|
850
|
+
limit: limit == null ? null : normalizeInteger(limit, 0),
|
|
792
851
|
}),
|
|
793
852
|
});
|
|
794
853
|
|
|
795
|
-
if (!
|
|
796
|
-
logger.error?.('[claworld:product-shell] world
|
|
797
|
-
status:
|
|
854
|
+
if (!searchResult.ok) {
|
|
855
|
+
logger.error?.('[claworld:product-shell] world member search failed', {
|
|
856
|
+
status: searchResult.status,
|
|
798
857
|
worldId: resolvedWorldId,
|
|
799
858
|
agentId: resolvedAgentId,
|
|
800
859
|
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
801
|
-
body:
|
|
860
|
+
body: searchResult.body,
|
|
802
861
|
});
|
|
803
|
-
throw createProductShellHttpError('
|
|
862
|
+
throw createProductShellHttpError('world_member_search', searchResult, {
|
|
804
863
|
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
805
864
|
worldId: resolvedWorldId,
|
|
806
865
|
});
|
|
807
866
|
}
|
|
808
867
|
|
|
809
|
-
return
|
|
810
|
-
|
|
811
|
-
agentId: resolvedAgentId,
|
|
868
|
+
return normalizeWorldMemberSearchResponse(searchResult.body, {
|
|
869
|
+
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
812
870
|
});
|
|
813
871
|
}
|
|
814
872
|
|
|
815
|
-
export async function
|
|
873
|
+
export async function fetchWorldCandidateFeed({
|
|
816
874
|
cfg = {},
|
|
817
875
|
accountId = null,
|
|
818
876
|
runtimeConfig = null,
|
|
819
877
|
worldId = null,
|
|
820
878
|
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,
|
|
830
879
|
limit = null,
|
|
831
880
|
fetchImpl,
|
|
832
881
|
logger = console,
|
|
833
882
|
} = {}) {
|
|
834
883
|
if (typeof fetchImpl !== 'function') {
|
|
835
|
-
throw new Error('fetch is unavailable for claworld product-shell
|
|
884
|
+
throw new Error('fetch is unavailable for claworld product-shell candidate feed helper');
|
|
836
885
|
}
|
|
837
886
|
|
|
838
887
|
const resolvedWorldId = normalizeText(worldId, null);
|
|
839
888
|
if (!resolvedWorldId) {
|
|
840
|
-
throw new Error('claworld product-shell
|
|
889
|
+
throw new Error('claworld product-shell candidate feed helper requires worldId');
|
|
841
890
|
}
|
|
842
891
|
|
|
843
892
|
const resolvedAgentId = normalizeText(agentId, null);
|
|
844
893
|
if (!resolvedAgentId) {
|
|
845
|
-
throw new Error('claworld product-shell
|
|
894
|
+
throw new Error('claworld product-shell candidate feed helper requires agentId');
|
|
846
895
|
}
|
|
847
896
|
|
|
848
897
|
const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
|
|
849
898
|
const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
|
|
899
|
+
const normalizedLimit = normalizeInteger(limit, 0);
|
|
850
900
|
const searchResult = await fetchJson(fetchImpl, `${baseUrl}/v1/worlds/${encodeURIComponent(resolvedWorldId)}/search`, {
|
|
851
901
|
method: 'POST',
|
|
852
902
|
headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
|
|
@@ -856,36 +906,60 @@ export async function searchWorldMembers({
|
|
|
856
906
|
}),
|
|
857
907
|
body: JSON.stringify({
|
|
858
908
|
agentId: resolvedAgentId,
|
|
859
|
-
query:
|
|
860
|
-
|
|
861
|
-
|
|
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),
|
|
909
|
+
query: null,
|
|
910
|
+
sort: 'match',
|
|
911
|
+
limit: normalizedLimit > 0 ? normalizedLimit : null,
|
|
869
912
|
}),
|
|
870
913
|
});
|
|
871
914
|
|
|
872
915
|
if (!searchResult.ok) {
|
|
873
|
-
logger.error?.('[claworld:product-shell]
|
|
916
|
+
logger.error?.('[claworld:product-shell] candidate feed compatibility search failed', {
|
|
874
917
|
status: searchResult.status,
|
|
875
918
|
worldId: resolvedWorldId,
|
|
876
919
|
agentId: resolvedAgentId,
|
|
877
920
|
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
878
921
|
body: searchResult.body,
|
|
879
922
|
});
|
|
880
|
-
throw createProductShellHttpError('
|
|
923
|
+
throw createProductShellHttpError('world_candidate_feed', searchResult, {
|
|
881
924
|
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
882
925
|
worldId: resolvedWorldId,
|
|
883
926
|
});
|
|
884
927
|
}
|
|
885
928
|
|
|
886
|
-
|
|
929
|
+
const searchPayload = searchResult.body && typeof searchResult.body === 'object' ? searchResult.body : {};
|
|
930
|
+
const normalizedSearch = normalizeWorldMemberSearchResponse(searchPayload, {
|
|
887
931
|
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
888
932
|
});
|
|
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
|
+
});
|
|
889
963
|
}
|
|
890
964
|
|
|
891
965
|
export async function resolveWorldSelectionFlow({
|