@xfxstudio/claworld 2026.7.7-testing.1 → 2026.7.8-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.
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/skills/claworld-manage-worlds/SKILL.md +9 -0
- package/skills/claworld-management-session/SKILL.md +1 -0
- package/src/openclaw/index.js +1 -0
- package/src/openclaw/plugin/claworld-channel-plugin.js +46 -2
- package/src/openclaw/plugin/register-tooling.js +99 -37
- package/src/openclaw/plugin/register.js +27 -5
- package/src/openclaw/runtime/world-membership-helper.js +157 -0
- package/src/product-shell/contracts/search-item.js +1 -0
package/openclaw.plugin.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"name": "Claworld Persona Relay",
|
|
19
19
|
"description": "Claworld relay world channel plugin for OpenClaw.",
|
|
20
|
-
"version": "2026.7.
|
|
20
|
+
"version": "2026.7.8-testing.1",
|
|
21
21
|
"configSchema": {
|
|
22
22
|
"type": "object",
|
|
23
23
|
"additionalProperties": false,
|
package/package.json
CHANGED
|
@@ -31,6 +31,7 @@ All world management goes through `claworld_manage_worlds`:
|
|
|
31
31
|
- `list_world_activity`
|
|
32
32
|
- `list_broadcast_history`
|
|
33
33
|
- `manage_members`
|
|
34
|
+
- `list_pending_invites`
|
|
34
35
|
- `list_invites`
|
|
35
36
|
- `invite_member`
|
|
36
37
|
- `revoke_invite`
|
|
@@ -95,12 +96,20 @@ When the human needs to create or update a world and `worldContextText` is empty
|
|
|
95
96
|
2. `update_world_profile` or `leave_world`
|
|
96
97
|
3. `subscribe_world` / `unsubscribe_world` when ongoing attention is desired
|
|
97
98
|
|
|
99
|
+
### Reviewing Received Invites
|
|
100
|
+
|
|
101
|
+
1. `list_pending_invites`
|
|
102
|
+
2. Treat the returned item as the pre-join private-world invitation preview.
|
|
103
|
+
3. Explain the inviter, inviter profile, world purpose, world fit, invitation note, lifecycle state, and available next actions in natural language.
|
|
104
|
+
4. Join with `join_world` only after the human confirms the world-scoped `participantContextText`.
|
|
105
|
+
|
|
98
106
|
## Quick Reference
|
|
99
107
|
|
|
100
108
|
- Create world: `claworld_manage_worlds(action=create_world, displayName, worldContextText, participantContextText)`
|
|
101
109
|
- Get world: `claworld_manage_worlds(action=get_world, worldId)`
|
|
102
110
|
- List owned: `claworld_manage_worlds(action=list_owned_worlds)`
|
|
103
111
|
- List joined: `claworld_manage_worlds(action=list_joined_worlds)`
|
|
112
|
+
- Pending invites received by this account: `claworld_manage_worlds(action=list_pending_invites)`
|
|
104
113
|
- Join world: `claworld_manage_worlds(action=join_world, worldId, participantContextText)`
|
|
105
114
|
- Update participant profile: `claworld_manage_worlds(action=update_world_profile, worldId, profileContextText)`
|
|
106
115
|
- Leave world: `claworld_manage_worlds(action=leave_world, worldId)`
|
|
@@ -91,6 +91,7 @@ Before starting or judging a conversation, usually check the relevant pieces:
|
|
|
91
91
|
- the owner's current goals and memory in `.claworld/`
|
|
92
92
|
- the person's public profile
|
|
93
93
|
- the world, membership, and join context
|
|
94
|
+
- pending world invitations received by this account
|
|
94
95
|
- existing active, opening, pending, silent, or ended conversations with the same person
|
|
95
96
|
|
|
96
97
|
Prefer the normal Claworld tools for product work:
|
package/src/openclaw/index.js
CHANGED
|
@@ -53,6 +53,7 @@ import {
|
|
|
53
53
|
revokeModeratedWorldInvite,
|
|
54
54
|
} from '../runtime/world-moderation-helper.js';
|
|
55
55
|
import {
|
|
56
|
+
fetchPendingWorldInvites,
|
|
56
57
|
fetchWorldMembership,
|
|
57
58
|
fetchWorldMemberships,
|
|
58
59
|
leaveWorldMembership,
|
|
@@ -271,6 +272,18 @@ function isClaworldPlainObject(value) {
|
|
|
271
272
|
return value && typeof value === 'object' && !Array.isArray(value);
|
|
272
273
|
}
|
|
273
274
|
|
|
275
|
+
function resolveAccountProfileEnvelope(payload = null) {
|
|
276
|
+
return isClaworldPlainObject(payload?.profile) ? payload.profile : null;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function resolveAccountAgentId(payload = null, fallback = null) {
|
|
280
|
+
const profile = resolveAccountProfileEnvelope(payload);
|
|
281
|
+
return normalizeClaworldText(
|
|
282
|
+
payload?.agentId,
|
|
283
|
+
normalizeClaworldText(profile?.agentId, fallback),
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
274
287
|
function resolveClaworldOpeningMessage({
|
|
275
288
|
openingMessage = null,
|
|
276
289
|
message = null,
|
|
@@ -2070,7 +2083,7 @@ async function ensureRelayBinding({ runtimeConfig, fetchImpl, logger }) {
|
|
|
2070
2083
|
expiresInSeconds: null,
|
|
2071
2084
|
fetchImpl,
|
|
2072
2085
|
});
|
|
2073
|
-
const resolvedAgentId =
|
|
2086
|
+
const resolvedAgentId = resolveAccountAgentId(identityPayload, null);
|
|
2074
2087
|
if (resolvedAgentId) {
|
|
2075
2088
|
return {
|
|
2076
2089
|
runtimeConfig: applyRuntimeIdentity(normalizedRuntimeConfig, { agentId: resolvedAgentId }),
|
|
@@ -4350,7 +4363,10 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
4350
4363
|
shareCardVariant: context.shareCardVariant ?? null,
|
|
4351
4364
|
fetchImpl,
|
|
4352
4365
|
});
|
|
4353
|
-
|
|
4366
|
+
const profileEnvelope = result?.profile && typeof result.profile === 'object' && !Array.isArray(result.profile)
|
|
4367
|
+
? result.profile
|
|
4368
|
+
: null;
|
|
4369
|
+
return profileEnvelope?.shareCard || {};
|
|
4354
4370
|
}
|
|
4355
4371
|
|
|
4356
4372
|
return {
|
|
@@ -4946,6 +4962,20 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
4946
4962
|
logger,
|
|
4947
4963
|
});
|
|
4948
4964
|
},
|
|
4965
|
+
listPendingInvites: async (context = {}) => {
|
|
4966
|
+
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
4967
|
+
return fetchPendingWorldInvites({
|
|
4968
|
+
cfg: resolvedContext.cfg || {},
|
|
4969
|
+
accountId: resolvedContext.accountId || null,
|
|
4970
|
+
runtimeConfig: resolvedContext.runtimeConfig || null,
|
|
4971
|
+
agentId: resolvedContext.agentId || null,
|
|
4972
|
+
status: context.status || 'pending',
|
|
4973
|
+
includeDisabled: context.includeDisabled !== false,
|
|
4974
|
+
limit: context.limit ?? null,
|
|
4975
|
+
fetchImpl,
|
|
4976
|
+
logger,
|
|
4977
|
+
});
|
|
4978
|
+
},
|
|
4949
4979
|
getWorldMembership: async (context = {}) => {
|
|
4950
4980
|
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
4951
4981
|
return fetchWorldMembership({
|
|
@@ -5372,6 +5402,20 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
5372
5402
|
logger,
|
|
5373
5403
|
});
|
|
5374
5404
|
},
|
|
5405
|
+
listPendingInvites: async (context = {}) => {
|
|
5406
|
+
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
5407
|
+
return fetchPendingWorldInvites({
|
|
5408
|
+
cfg: resolvedContext.cfg || {},
|
|
5409
|
+
accountId: resolvedContext.accountId || null,
|
|
5410
|
+
runtimeConfig: resolvedContext.runtimeConfig || null,
|
|
5411
|
+
agentId: resolvedContext.agentId || null,
|
|
5412
|
+
status: context.status || 'pending',
|
|
5413
|
+
includeDisabled: context.includeDisabled !== false,
|
|
5414
|
+
limit: context.limit ?? null,
|
|
5415
|
+
fetchImpl,
|
|
5416
|
+
logger,
|
|
5417
|
+
});
|
|
5418
|
+
},
|
|
5375
5419
|
getWorldMembership: async (context = {}) => {
|
|
5376
5420
|
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
5377
5421
|
return fetchWorldMembership({
|
|
@@ -32,6 +32,56 @@ export function normalizeObject(value, fallback = null) {
|
|
|
32
32
|
return value;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function normalizePlainText(value, fallback = null) {
|
|
36
|
+
if (value == null || typeof value === 'object' || typeof value === 'function') return fallback;
|
|
37
|
+
return normalizeText(value, fallback);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function resolveAccountManagementProfilePayload(payload = null) {
|
|
41
|
+
return normalizeObject(payload?.profile, null);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function resolveToolIdentityPayload(payload = null) {
|
|
45
|
+
return resolveAccountManagementProfilePayload(payload) || normalizeObject(payload, null);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function resolveToolPublicIdentityPayload(payload = null) {
|
|
49
|
+
const identityPayload = resolveToolIdentityPayload(payload);
|
|
50
|
+
return normalizeObject(identityPayload?.publicIdentity, null);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function resolveToolAccountProfilePayload(payload = null) {
|
|
54
|
+
const identityPayload = resolveToolIdentityPayload(payload);
|
|
55
|
+
return normalizeObject(identityPayload?.accountProfile, null);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function resolveToolShareCardPayload(payload = null) {
|
|
59
|
+
const identityPayload = resolveToolIdentityPayload(payload);
|
|
60
|
+
if (identityPayload && Object.prototype.hasOwnProperty.call(identityPayload, 'shareCard')) {
|
|
61
|
+
return identityPayload.shareCard;
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function resolveToolPluginVersionPayload(payload = null) {
|
|
67
|
+
const identityPayload = resolveToolIdentityPayload(payload);
|
|
68
|
+
return identityPayload?.clientVersionStatus || null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function resolveToolAgentId(payload = null, fallback = null) {
|
|
72
|
+
const identityPayload = resolveToolIdentityPayload(payload);
|
|
73
|
+
return normalizePlainText(identityPayload?.agentId, fallback);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function resolveToolDisplayName(payload = null, fallback = null) {
|
|
77
|
+
const identityPayload = resolveToolIdentityPayload(payload);
|
|
78
|
+
const publicIdentity = resolveToolPublicIdentityPayload(payload);
|
|
79
|
+
return normalizePlainText(
|
|
80
|
+
publicIdentity?.displayName,
|
|
81
|
+
normalizePlainText(identityPayload?.recommendedDisplayName, fallback),
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
35
85
|
function resolveRuntimeAppToken(runtimeConfig = {}) {
|
|
36
86
|
return normalizeText(
|
|
37
87
|
runtimeConfig?.appToken,
|
|
@@ -94,7 +144,7 @@ async function buildPendingPublicIdentityError({
|
|
|
94
144
|
accountId: normalizeText(accountId, null),
|
|
95
145
|
agentId: normalizeText(
|
|
96
146
|
agentId,
|
|
97
|
-
|
|
147
|
+
resolveToolAgentId(identityPayload, null),
|
|
98
148
|
),
|
|
99
149
|
httpStatus: 409,
|
|
100
150
|
backendCode: 'public_identity_incomplete',
|
|
@@ -512,31 +562,36 @@ export function inferAccountAction(params = {}) {
|
|
|
512
562
|
}
|
|
513
563
|
|
|
514
564
|
function projectToolPublicIdentity(payload = null) {
|
|
515
|
-
|
|
565
|
+
const identityPayload = resolveToolIdentityPayload(payload);
|
|
566
|
+
if (!identityPayload) return null;
|
|
567
|
+
const publicIdentity = resolveToolPublicIdentityPayload(payload);
|
|
516
568
|
return {
|
|
517
|
-
status:
|
|
518
|
-
ready:
|
|
519
|
-
publicIdentity:
|
|
569
|
+
status: normalizePlainText(identityPayload.status, null),
|
|
570
|
+
ready: identityPayload.ready ?? null,
|
|
571
|
+
publicIdentity: publicIdentity
|
|
520
572
|
? {
|
|
521
|
-
status:
|
|
522
|
-
displayIdentity:
|
|
523
|
-
displayName:
|
|
524
|
-
code:
|
|
525
|
-
confirmedAt:
|
|
526
|
-
updatedAt:
|
|
573
|
+
status: normalizePlainText(publicIdentity.status, null),
|
|
574
|
+
displayIdentity: normalizePlainText(publicIdentity.displayIdentity, null),
|
|
575
|
+
displayName: normalizePlainText(publicIdentity.displayName, null),
|
|
576
|
+
code: normalizePlainText(publicIdentity.code, null),
|
|
577
|
+
confirmedAt: normalizePlainText(publicIdentity.confirmedAt, null),
|
|
578
|
+
updatedAt: normalizePlainText(publicIdentity.updatedAt, null),
|
|
527
579
|
}
|
|
528
580
|
: null,
|
|
529
|
-
recommendedDisplayName:
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
581
|
+
recommendedDisplayName: normalizePlainText(
|
|
582
|
+
identityPayload.recommendedDisplayName,
|
|
583
|
+
null,
|
|
584
|
+
),
|
|
585
|
+
requiredAction: normalizePlainText(identityPayload.requiredAction, null),
|
|
586
|
+
nextAction: normalizePlainText(identityPayload.nextAction, null),
|
|
587
|
+
nextTool: normalizePlainText(identityPayload.nextTool, null),
|
|
588
|
+
missingFields: Array.isArray(identityPayload.missingFields) ? identityPayload.missingFields : [],
|
|
589
|
+
feedbackSummary: identityPayload.feedbackSummary && typeof identityPayload.feedbackSummary === 'object'
|
|
535
590
|
? {
|
|
536
|
-
totalLikesReceived: Number(
|
|
537
|
-
totalDislikesReceived: Number(
|
|
538
|
-
totalLikesGiven: Number(
|
|
539
|
-
totalDislikesGiven: Number(
|
|
591
|
+
totalLikesReceived: Number(identityPayload.feedbackSummary.totalLikesReceived || 0),
|
|
592
|
+
totalDislikesReceived: Number(identityPayload.feedbackSummary.totalDislikesReceived || 0),
|
|
593
|
+
totalLikesGiven: Number(identityPayload.feedbackSummary.totalLikesGiven || 0),
|
|
594
|
+
totalDislikesGiven: Number(identityPayload.feedbackSummary.totalDislikesGiven || 0),
|
|
540
595
|
}
|
|
541
596
|
: null,
|
|
542
597
|
};
|
|
@@ -596,23 +651,28 @@ function projectToolAccountIdentityFields(identityPayload = null) {
|
|
|
596
651
|
}
|
|
597
652
|
|
|
598
653
|
function projectToolAccountProfile(identityPayload = null) {
|
|
599
|
-
|
|
654
|
+
const identityPayloadSource = resolveToolIdentityPayload(identityPayload);
|
|
655
|
+
const profilePayload = resolveToolAccountProfilePayload(identityPayload);
|
|
656
|
+
return normalizePlainText(
|
|
657
|
+
profilePayload?.profile,
|
|
658
|
+
normalizePlainText(identityPayloadSource?.profile, null),
|
|
659
|
+
);
|
|
600
660
|
}
|
|
601
661
|
|
|
602
662
|
function projectToolAccountProfileState(identityPayload = null) {
|
|
603
|
-
const profilePayload =
|
|
604
|
-
const profile =
|
|
663
|
+
const profilePayload = resolveToolAccountProfilePayload(identityPayload);
|
|
664
|
+
const profile = normalizePlainText(profilePayload?.profile, projectToolAccountProfile(identityPayload));
|
|
605
665
|
const ready = profilePayload
|
|
606
666
|
? profilePayload.ready === true
|
|
607
667
|
: Boolean(profile);
|
|
608
668
|
return {
|
|
609
|
-
status:
|
|
669
|
+
status: normalizePlainText(profilePayload?.status, ready ? 'ready' : 'pending'),
|
|
610
670
|
ready,
|
|
611
671
|
profile,
|
|
612
|
-
reason:
|
|
613
|
-
requiredAction:
|
|
614
|
-
nextAction:
|
|
615
|
-
nextTool:
|
|
672
|
+
reason: normalizePlainText(profilePayload?.reason, ready ? null : 'account_profile_missing'),
|
|
673
|
+
requiredAction: normalizePlainText(profilePayload?.requiredAction, ready ? null : 'update_agent_profile'),
|
|
674
|
+
nextAction: normalizePlainText(profilePayload?.nextAction, ready ? null : 'update_agent_profile'),
|
|
675
|
+
nextTool: normalizePlainText(profilePayload?.nextTool, ready ? null : 'claworld_manage_account'),
|
|
616
676
|
missingFields: Array.isArray(profilePayload?.missingFields)
|
|
617
677
|
? profilePayload.missingFields
|
|
618
678
|
: (ready
|
|
@@ -630,9 +690,9 @@ function projectToolAccountProfileState(identityPayload = null) {
|
|
|
630
690
|
function resolveToolPublicIdentityReady(identityPayload = null, publicIdentityState = {}) {
|
|
631
691
|
const diagnostics = normalizeObject(identityPayload?.diagnostics, null);
|
|
632
692
|
if (typeof diagnostics?.publicIdentityReady === 'boolean') return diagnostics.publicIdentityReady;
|
|
633
|
-
const identityStatus =
|
|
693
|
+
const identityStatus = normalizePlainText(publicIdentityState?.publicIdentity?.status, null);
|
|
634
694
|
if (identityStatus) return identityStatus === 'ready';
|
|
635
|
-
return identityPayload?.ready === true;
|
|
695
|
+
return resolveToolIdentityPayload(identityPayload)?.ready === true || identityPayload?.ready === true;
|
|
636
696
|
}
|
|
637
697
|
|
|
638
698
|
function projectToolPluginVersionStatus(payload = null) {
|
|
@@ -746,8 +806,9 @@ export function projectToolAccountViewResponse({
|
|
|
746
806
|
const relayResolved = typeof accountRelay?.resolved === 'boolean'
|
|
747
807
|
? accountRelay.resolved
|
|
748
808
|
: (typeof relayOnline === 'boolean');
|
|
749
|
-
const
|
|
750
|
-
|
|
809
|
+
const shareCardPayload = resolveToolShareCardPayload(identityPayload);
|
|
810
|
+
const resolvedShareCard = shareCardPayload !== undefined
|
|
811
|
+
? projectToolShareCard(shareCardPayload)
|
|
751
812
|
: undefined;
|
|
752
813
|
return {
|
|
753
814
|
action: 'view',
|
|
@@ -799,7 +860,7 @@ export function projectToolAccountViewResponse({
|
|
|
799
860
|
nextAction: blockedAction.nextAction,
|
|
800
861
|
nextTool: blockedAction.nextTool,
|
|
801
862
|
missingFields: blockedAction.missingFields,
|
|
802
|
-
pluginVersionStatus: projectToolPluginVersionStatus(identityPayload
|
|
863
|
+
pluginVersionStatus: projectToolPluginVersionStatus(resolveToolPluginVersionPayload(identityPayload)),
|
|
803
864
|
...(resolvedShareCard !== undefined ? { shareCard: resolvedShareCard } : {}),
|
|
804
865
|
};
|
|
805
866
|
}
|
|
@@ -813,10 +874,11 @@ export function projectToolAccountMutationResponse({
|
|
|
813
874
|
} = {}) {
|
|
814
875
|
const publicIdentityState = projectToolAccountIdentityFields(identityPayload);
|
|
815
876
|
const accountProfile = projectToolAccountProfileState(identityPayload);
|
|
877
|
+
const identityShareCardPayload = resolveToolShareCardPayload(identityPayload);
|
|
816
878
|
const resolvedShareCard = shareCard !== undefined
|
|
817
879
|
? shareCard
|
|
818
|
-
: (
|
|
819
|
-
? projectToolShareCard(
|
|
880
|
+
: (identityShareCardPayload !== undefined
|
|
881
|
+
? projectToolShareCard(identityShareCardPayload)
|
|
820
882
|
: undefined);
|
|
821
883
|
const publicIdentityReady = resolveToolPublicIdentityReady(identityPayload, publicIdentityState);
|
|
822
884
|
const accountProfileReady = accountProfile.ready === true;
|
|
@@ -885,7 +947,7 @@ export function projectToolAccountMutationResponse({
|
|
|
885
947
|
nextTool: blockedAction.nextTool,
|
|
886
948
|
missingFields: blockedAction.missingFields,
|
|
887
949
|
reason: blockedAction.reason,
|
|
888
|
-
pluginVersionStatus: projectToolPluginVersionStatus(identityPayload
|
|
950
|
+
pluginVersionStatus: projectToolPluginVersionStatus(resolveToolPluginVersionPayload(identityPayload)),
|
|
889
951
|
...(resolvedShareCard !== undefined ? { shareCard: resolvedShareCard } : {}),
|
|
890
952
|
...(runtimeIdentity ? { runtimeIdentity } : {}),
|
|
891
953
|
...(action === 'update_identity'
|
|
@@ -50,6 +50,8 @@ import {
|
|
|
50
50
|
projectToolManageWorldActionResponse,
|
|
51
51
|
requireManageWorldField,
|
|
52
52
|
resolveToolContext,
|
|
53
|
+
resolveToolAgentId,
|
|
54
|
+
resolveToolDisplayName,
|
|
53
55
|
stringParam,
|
|
54
56
|
withToolErrorBoundary,
|
|
55
57
|
} from './register-tooling.js';
|
|
@@ -686,6 +688,13 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
686
688
|
shareCardVariant: params.shareCardVariant ?? null,
|
|
687
689
|
expiresInSeconds: params.expiresInSeconds ?? null,
|
|
688
690
|
});
|
|
691
|
+
if (action === 'update_display_name') {
|
|
692
|
+
return buildToolResult(projectToolAccountMutationResponse({
|
|
693
|
+
action,
|
|
694
|
+
accountId: context.accountId,
|
|
695
|
+
identityPayload: payload,
|
|
696
|
+
}));
|
|
697
|
+
}
|
|
689
698
|
return buildTerminalActionResult({ tool: accountTool, action, payload });
|
|
690
699
|
},
|
|
691
700
|
},
|
|
@@ -888,6 +897,7 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
888
897
|
category: 'world_management',
|
|
889
898
|
usageNotes: [
|
|
890
899
|
'action=join_world joins a visible world with world-scoped profile text.',
|
|
900
|
+
'action=list_pending_invites lists pending world invitations received by the current account.',
|
|
891
901
|
'action=create_world creates an owner-managed world.',
|
|
892
902
|
'Owner governance and member self-service actions use terminal action names such as update_world, publish_broadcast, and update_world_profile.',
|
|
893
903
|
'Subscription, activity, and member-list actions are backed by the product-shell terminal routes.',
|
|
@@ -1007,6 +1017,18 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
1007
1017
|
});
|
|
1008
1018
|
return buildTerminalActionResult({ tool: manageWorldsTool, action, payload });
|
|
1009
1019
|
}
|
|
1020
|
+
if (action === 'list_pending_invites') {
|
|
1021
|
+
const context = await resolveToolContext(api, plugin, params, {
|
|
1022
|
+
requiredPublicIdentityCapability: 'list pending world invites',
|
|
1023
|
+
});
|
|
1024
|
+
const payload = await plugin.runtime.productShell.membership.listPendingInvites({
|
|
1025
|
+
...context,
|
|
1026
|
+
status: params.status || 'pending',
|
|
1027
|
+
includeDisabled: params.includeDisabled !== false,
|
|
1028
|
+
limit: params.limit ?? null,
|
|
1029
|
+
});
|
|
1030
|
+
return buildTerminalActionResult({ tool: manageWorldsTool, action, payload });
|
|
1031
|
+
}
|
|
1010
1032
|
if (action === 'list_invites') {
|
|
1011
1033
|
const worldId = normalizeText(params.worldId, null);
|
|
1012
1034
|
if (!worldId) requireManageWorldField('worldId');
|
|
@@ -2032,7 +2054,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
2032
2054
|
shareCardVariant: params.shareCardVariant ?? null,
|
|
2033
2055
|
expiresInSeconds: params.expiresInSeconds ?? null,
|
|
2034
2056
|
});
|
|
2035
|
-
const pairedAgentId = identityPayload
|
|
2057
|
+
const pairedAgentId = resolveToolAgentId(identityPayload, runtimeConfig.relay?.agentId || null);
|
|
2036
2058
|
const pairedRuntimeConfig = pairedAgentId
|
|
2037
2059
|
? {
|
|
2038
2060
|
...runtimeConfig,
|
|
@@ -2045,11 +2067,11 @@ function buildRegisteredTools(api, plugin) {
|
|
|
2045
2067
|
const relayAgentFallback = pairedAgentId
|
|
2046
2068
|
? {
|
|
2047
2069
|
agentId: pairedAgentId,
|
|
2048
|
-
displayName:
|
|
2049
|
-
identityPayload
|
|
2070
|
+
displayName: resolveToolDisplayName(
|
|
2071
|
+
identityPayload,
|
|
2050
2072
|
normalizeText(
|
|
2051
|
-
|
|
2052
|
-
normalizeText(runtimeConfig?.
|
|
2073
|
+
runtimeConfig?.name,
|
|
2074
|
+
normalizeText(runtimeConfig?.registration?.displayName, null),
|
|
2053
2075
|
),
|
|
2054
2076
|
),
|
|
2055
2077
|
visibilityMode: null,
|
|
@@ -15,6 +15,23 @@ function normalizeOptionalBoolean(value, fallback = null) {
|
|
|
15
15
|
return fallback;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
function normalizeOptionalInteger(value, fallback = null) {
|
|
19
|
+
const parsed = Number(value);
|
|
20
|
+
if (!Number.isFinite(parsed)) return fallback;
|
|
21
|
+
return Math.trunc(parsed);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function normalizePositiveInteger(value, fallback = null) {
|
|
25
|
+
const parsed = Number(value);
|
|
26
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
|
|
27
|
+
return Math.max(1, Math.trunc(parsed));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function normalizeStringList(values = []) {
|
|
31
|
+
if (!Array.isArray(values)) return [];
|
|
32
|
+
return [...new Set(values.map((value) => normalizeText(value, null)).filter(Boolean))];
|
|
33
|
+
}
|
|
34
|
+
|
|
18
35
|
function normalizeWorldRole(worldRole, fallback = null) {
|
|
19
36
|
const normalized = normalizeText(worldRole, fallback);
|
|
20
37
|
return ['owner', 'member'].includes(normalized) ? normalized : fallback;
|
|
@@ -38,6 +55,97 @@ function normalizeManagedWorldMembership(payload = {}) {
|
|
|
38
55
|
};
|
|
39
56
|
}
|
|
40
57
|
|
|
58
|
+
function normalizePendingInviteAction(action = null) {
|
|
59
|
+
if (!action || typeof action !== 'object' || Array.isArray(action)) return null;
|
|
60
|
+
return {
|
|
61
|
+
action: normalizeText(action.action, null),
|
|
62
|
+
tool: normalizeText(action.tool, null),
|
|
63
|
+
worldId: normalizeText(action.worldId, null),
|
|
64
|
+
requiredFields: normalizeStringList(action.requiredFields),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function normalizeParticipantContextField(field = null) {
|
|
69
|
+
if (!field || typeof field !== 'object' || Array.isArray(field)) return null;
|
|
70
|
+
return {
|
|
71
|
+
fieldId: normalizeText(field.fieldId, null),
|
|
72
|
+
label: normalizeText(field.label, null),
|
|
73
|
+
description: normalizeText(field.description, null),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function normalizeJoinPlan(plan = null) {
|
|
78
|
+
if (!plan || typeof plan !== 'object' || Array.isArray(plan)) return null;
|
|
79
|
+
return {
|
|
80
|
+
worldId: normalizeText(plan.worldId, null),
|
|
81
|
+
participantContextField: normalizeParticipantContextField(plan.participantContextField),
|
|
82
|
+
nextAction: normalizeText(plan.nextAction, null),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function normalizeInviterProfile(inviter = null) {
|
|
87
|
+
if (!inviter || typeof inviter !== 'object' || Array.isArray(inviter)) return null;
|
|
88
|
+
return {
|
|
89
|
+
agentId: normalizeText(inviter.agentId, null),
|
|
90
|
+
displayName: normalizeText(inviter.displayName, null),
|
|
91
|
+
publicIdentity: normalizeText(inviter.publicIdentity, null),
|
|
92
|
+
profile: normalizeText(inviter.profile, null),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function normalizeInviteLifecycle(lifecycle = null) {
|
|
97
|
+
if (!lifecycle || typeof lifecycle !== 'object' || Array.isArray(lifecycle)) return null;
|
|
98
|
+
return {
|
|
99
|
+
status: normalizeText(lifecycle.status, null),
|
|
100
|
+
expiresAt: normalizeText(lifecycle.expiresAt, null),
|
|
101
|
+
expirationPolicy: normalizeText(lifecycle.expirationPolicy, null),
|
|
102
|
+
acceptedAt: normalizeText(lifecycle.acceptedAt, null),
|
|
103
|
+
inviteRevokedAt: normalizeText(lifecycle.inviteRevokedAt, null),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function normalizePendingWorldInvite(payload = {}) {
|
|
108
|
+
return {
|
|
109
|
+
invitationId: normalizeText(payload.invitationId, null),
|
|
110
|
+
membershipId: normalizeText(payload.membershipId, null),
|
|
111
|
+
agentId: normalizeText(payload.agentId, null),
|
|
112
|
+
worldId: normalizeText(payload.worldId, null),
|
|
113
|
+
displayName: normalizeText(payload.displayName, null),
|
|
114
|
+
worldContextText: normalizeText(payload.worldContextText, null),
|
|
115
|
+
participantContextField: normalizeParticipantContextField(payload.participantContextField),
|
|
116
|
+
joinPlan: normalizeJoinPlan(payload.joinPlan),
|
|
117
|
+
membershipStatus: normalizeText(payload.membershipStatus, null),
|
|
118
|
+
status: normalizeText(payload.status, null),
|
|
119
|
+
invitedByAgentId: normalizeText(payload.invitedByAgentId, null),
|
|
120
|
+
invitedByDisplayName: normalizeText(payload.invitedByDisplayName, null),
|
|
121
|
+
invitedByPublicIdentity: normalizeText(payload.invitedByPublicIdentity, null),
|
|
122
|
+
inviter: normalizeInviterProfile(payload.inviter),
|
|
123
|
+
invitedAt: normalizeText(payload.invitedAt, null),
|
|
124
|
+
inviteMessage: normalizeText(payload.inviteMessage, null),
|
|
125
|
+
expiresAt: normalizeText(payload.expiresAt, null),
|
|
126
|
+
expirationPolicy: normalizeText(payload.expirationPolicy, null),
|
|
127
|
+
lifecycle: normalizeInviteLifecycle(payload.lifecycle),
|
|
128
|
+
membershipUpdatedAt: normalizeText(payload.membershipUpdatedAt, null),
|
|
129
|
+
worldUpdatedAt: normalizeText(payload.worldUpdatedAt, null),
|
|
130
|
+
nextAction: normalizeText(payload.nextAction, null),
|
|
131
|
+
nextActions: Array.isArray(payload.nextActions)
|
|
132
|
+
? payload.nextActions.map((action) => normalizePendingInviteAction(action)).filter(Boolean)
|
|
133
|
+
: [],
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function normalizePendingWorldInviteList(payload = {}) {
|
|
138
|
+
return {
|
|
139
|
+
agentId: normalizeText(payload.agentId, null),
|
|
140
|
+
status: normalizeText(payload.status, null),
|
|
141
|
+
items: Array.isArray(payload.items)
|
|
142
|
+
? payload.items.map((item) => normalizePendingWorldInvite(item))
|
|
143
|
+
: [],
|
|
144
|
+
totalItems: normalizeOptionalInteger(payload.totalItems, 0),
|
|
145
|
+
nextAction: normalizeText(payload.nextAction, null),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
41
149
|
function normalizeMembershipList(payload = {}) {
|
|
42
150
|
return {
|
|
43
151
|
items: Array.isArray(payload.items)
|
|
@@ -116,6 +224,55 @@ export async function fetchWorldMemberships({
|
|
|
116
224
|
return normalizeMembershipList(result.body);
|
|
117
225
|
}
|
|
118
226
|
|
|
227
|
+
export async function fetchPendingWorldInvites({
|
|
228
|
+
cfg = {},
|
|
229
|
+
accountId = null,
|
|
230
|
+
runtimeConfig = null,
|
|
231
|
+
agentId = null,
|
|
232
|
+
status = 'pending',
|
|
233
|
+
includeDisabled = true,
|
|
234
|
+
limit = null,
|
|
235
|
+
fetchImpl,
|
|
236
|
+
logger = console,
|
|
237
|
+
} = {}) {
|
|
238
|
+
if (typeof fetchImpl !== 'function') {
|
|
239
|
+
throw new Error('fetch is unavailable for claworld world membership helper');
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const resolvedAgentId = normalizeText(agentId, null);
|
|
243
|
+
if (!resolvedAgentId) {
|
|
244
|
+
throw new Error('claworld world membership helper requires agentId');
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
|
|
248
|
+
const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
|
|
249
|
+
const requestUrl = new URL(`${baseUrl}/v1/world-invitations`);
|
|
250
|
+
requestUrl.searchParams.set('agentId', resolvedAgentId);
|
|
251
|
+
requestUrl.searchParams.set('status', normalizeText(status, 'pending'));
|
|
252
|
+
requestUrl.searchParams.set('includeDisabled', includeDisabled ? 'true' : 'false');
|
|
253
|
+
const normalizedLimit = normalizePositiveInteger(limit, null);
|
|
254
|
+
if (normalizedLimit) requestUrl.searchParams.set('limit', String(normalizedLimit));
|
|
255
|
+
const result = await fetchJson(fetchImpl, requestUrl.toString(), {
|
|
256
|
+
headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
|
|
257
|
+
accept: 'application/json',
|
|
258
|
+
...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
|
|
259
|
+
}),
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
if (!result.ok) {
|
|
263
|
+
logger.error?.('[claworld:membership] pending world invites fetch failed', {
|
|
264
|
+
status: result.status,
|
|
265
|
+
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
266
|
+
body: result.body,
|
|
267
|
+
});
|
|
268
|
+
throw createWorldMembershipHttpError('list_pending_invites', result, {
|
|
269
|
+
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return normalizePendingWorldInviteList(result.body);
|
|
274
|
+
}
|
|
275
|
+
|
|
119
276
|
export async function fetchWorldMembership({
|
|
120
277
|
cfg = {},
|
|
121
278
|
accountId = null,
|