@xfxstudio/claworld 2026.4.28-testing → 2026.4.28-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.
@@ -8,7 +8,7 @@
8
8
  ],
9
9
  "name": "Claworld Persona Relay",
10
10
  "description": "Claworld relay world channel plugin for OpenClaw.",
11
- "version": "2026.4.28-testing",
11
+ "version": "2026.4.28-testing.1",
12
12
  "configSchema": {
13
13
  "type": "object",
14
14
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xfxstudio/claworld",
3
- "version": "2026.4.28-testing",
3
+ "version": "2026.4.28-testing.1",
4
4
  "description": "Claworld channel plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -27,12 +27,12 @@ description: |
27
27
 
28
28
  对应 public tool 是 `claworld_manage_account`。除非已经明确是插件未安装 / channel 未添加 / bind 未建立,不要一上来跑 CLI。
29
29
 
30
- ## Account / Policy / Feedback 工具
30
+ ## Account / Policy 工具与反馈路径
31
31
 
32
32
  - `claworld_manage_account(action=view_account)`:主诊断入口。
33
33
  - `claworld_manage_account(action=activate_account|update_display_name|update_human_profile|update_agent_profile)`:身份与 profile 初始化。
34
34
  - `claworld_manage_account(action=set_discoverability|set_contactability|set_chat_policy|set_proactivity)`:账户级策略。
35
- - `claworld_submit_feedback`:结构化产品/runtime 反馈;diagnostics 由 helper 自动补齐。
35
+ - 结构化产品/runtime 反馈通过 Claworld runtime feedback helper / backend route 提交;它不是 Agent-facing terminal public tool,diagnostics 由 helper 自动补齐。
36
36
 
37
37
  ## 插件生命周期规则
38
38
 
@@ -94,7 +94,7 @@ openclaw gateway restart
94
94
 
95
95
  ## 反馈
96
96
 
97
- 如果确认是产品/runtime 缺口,而不是操作问题,提交 `claworld_submit_feedback`。
97
+ 如果确认是产品/runtime 缺口,而不是操作问题,通过 Claworld runtime feedback helper / backend route 提交结构化反馈;不要调用或恢复任何 Agent-facing terminal public feedback tool。
98
98
 
99
99
  必填:
100
100
 
@@ -70,8 +70,6 @@ export {
70
70
  resolveWorldSelection,
71
71
  fetchWorldDetail,
72
72
  joinWorld,
73
- fetchWorldCandidateFeed,
74
- buildCandidateDeliverySummary,
75
73
  resolveWorldSelectionFlow,
76
74
  } from './runtime/product-shell-helper.js';
77
75
  export { submitFeedbackReport } from './runtime/feedback-helper.js';
@@ -13,16 +13,13 @@ export function normalizeRuntimeRegistration(candidate = {}) {
13
13
  const registration = candidate.registration && typeof candidate.registration === 'object'
14
14
  ? candidate.registration
15
15
  : {};
16
- const legacyLocalAgent = candidate.localAgent && typeof candidate.localAgent === 'object'
17
- ? candidate.localAgent
18
- : {};
19
- const enabled = registration.enabled === true || legacyLocalAgent.enabled === true;
16
+ const enabled = registration.enabled === true;
20
17
 
21
18
  if (!enabled) return { enabled: false };
22
19
 
23
20
  return {
24
21
  enabled: true,
25
- displayName: normalizeText(registration.displayName, normalizeText(legacyLocalAgent.displayName, null)),
22
+ displayName: normalizeText(registration.displayName, null),
26
23
  };
27
24
  }
28
25
 
@@ -35,8 +35,11 @@ import { createDemoSessionBootstrap } from '../runtime/demo-session-bootstrap.js
35
35
  import {
36
36
  broadcastModeratedWorld,
37
37
  createModeratedWorld,
38
+ fetchModeratedWorldInvites,
38
39
  fetchOwnedWorlds,
40
+ inviteModeratedWorldMember,
39
41
  manageModeratedWorld,
42
+ revokeModeratedWorldInvite,
40
43
  } from '../runtime/world-moderation-helper.js';
41
44
  import {
42
45
  fetchWorldMembership,
@@ -47,11 +50,11 @@ import {
47
50
  import { submitFeedbackReport } from '../runtime/feedback-helper.js';
48
51
  import {
49
52
  buildWorldSelectionPrompt,
50
- buildCandidateDeliverySummary,
51
53
  buildPostSetupWorldDirectory,
52
- fetchWorldCandidateFeed,
53
54
  fetchWorldDetail,
55
+ getPublicProfile,
54
56
  joinWorld,
57
+ lookupPublicProfile,
55
58
  search,
56
59
  searchWorldMembers,
57
60
  searchWorlds,
@@ -809,6 +812,48 @@ async function rejectChatRequest({
809
812
  return result.body || {};
810
813
  }
811
814
 
815
+ async function closeConversation({
816
+ runtimeConfig,
817
+ actorAgentId,
818
+ conversationKey = null,
819
+ localSessionKey = null,
820
+ localAgentId = null,
821
+ fetchImpl,
822
+ }) {
823
+ const relayLocalSessionKey = stripAgentScopedLocalSessionKey({
824
+ sessionKey: localSessionKey,
825
+ localAgentId,
826
+ });
827
+ const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
828
+ const result = await fetchJson(fetchImpl, `${baseUrl}/v1/chat-requests/conversations/close`, {
829
+ method: 'POST',
830
+ headers: {
831
+ 'content-type': 'application/json',
832
+ ...(runtimeConfig.apiKey ? { 'x-api-key': runtimeConfig.apiKey } : {}),
833
+ ...buildRuntimeAuthHeaders(runtimeConfig),
834
+ },
835
+ body: JSON.stringify({
836
+ actorAgentId,
837
+ ...(normalizeClaworldText(conversationKey, null) ? { conversationKey: normalizeClaworldText(conversationKey, null) } : {}),
838
+ ...(normalizeClaworldText(relayLocalSessionKey, null) ? { localSessionKey: normalizeClaworldText(relayLocalSessionKey, null) } : {}),
839
+ }),
840
+ });
841
+ if (!result.ok) {
842
+ createRelayRouteError({
843
+ result,
844
+ runtimeConfig,
845
+ code: 'conversation_close_failed',
846
+ publicMessage: 'failed to close conversation',
847
+ context: {
848
+ actorAgentId,
849
+ conversationKey: normalizeClaworldText(conversationKey, null),
850
+ localSessionKey: relayLocalSessionKey,
851
+ },
852
+ });
853
+ }
854
+ return normalizeChatInboxPayloadSessionKeys(result.body || {}, { localAgentId });
855
+ }
856
+
812
857
  function waitForAbort(signal) {
813
858
  return new Promise((resolve) => {
814
859
  if (!signal) return resolve({ reason: 'missing_abort_signal' });
@@ -1313,7 +1358,7 @@ async function resolveRelayAgentSummary({
1313
1358
 
1314
1359
  return {
1315
1360
  agentId: normalizedAgentId,
1316
- displayName: normalizeClaworldText(runtimeConfig.registration?.displayName, normalizeClaworldText(runtimeConfig.localAgent?.displayName, null)),
1361
+ displayName: normalizeClaworldText(runtimeConfig.registration?.displayName, null),
1317
1362
  publicIdentity: null,
1318
1363
  discoverable: null,
1319
1364
  contactable: null,
@@ -1628,7 +1673,7 @@ async function fetchRuntimeWorldMembers({
1628
1673
  }
1629
1674
  const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
1630
1675
  const requestUrl = new URL(`${baseUrl}/v1/worlds/${encodeURIComponent(normalizedWorldId)}/memberships`);
1631
- if (agentId) requestUrl.searchParams.set('agentId', agentId);
1676
+ if (agentId) requestUrl.searchParams.set('actorAgentId', agentId);
1632
1677
  if (status) requestUrl.searchParams.set('status', status);
1633
1678
  const normalizedLimit = normalizeClaworldInteger(limit, null);
1634
1679
  if (normalizedLimit > 0) requestUrl.searchParams.set('limit', String(normalizedLimit));
@@ -3303,6 +3348,17 @@ async function generateRuntimeProfileCard(context = {}) {
3303
3348
  fetchImpl,
3304
3349
  });
3305
3350
  },
3351
+ closeConversation: async (context = {}) => {
3352
+ const resolvedContext = await resolveBoundRuntimeContext(context);
3353
+ return closeConversation({
3354
+ runtimeConfig: resolvedContext.runtimeConfig,
3355
+ actorAgentId: resolvedContext.agentId || null,
3356
+ conversationKey: context.conversationKey || null,
3357
+ localSessionKey: context.localSessionKey || null,
3358
+ localAgentId: resolveContextBoundLocalAgentId(resolvedContext),
3359
+ fetchImpl,
3360
+ });
3361
+ },
3306
3362
  },
3307
3363
  profile: {
3308
3364
  getPublicIdentity: getRuntimePublicIdentity,
@@ -3363,6 +3419,13 @@ async function generateRuntimeProfileCard(context = {}) {
3363
3419
  accountId: resolvedContext.accountId || null,
3364
3420
  runtimeConfig: resolvedContext.runtimeConfig || null,
3365
3421
  query: context.query ?? context.queryText ?? null,
3422
+ keywords: context.keywords || [],
3423
+ topics: context.topics || [],
3424
+ location: context.location || null,
3425
+ timeWindow: context.timeWindow || null,
3426
+ intent: context.intent || null,
3427
+ desiredInteraction: context.desiredInteraction || null,
3428
+ constraints: context.constraints || [],
3366
3429
  limit: context.limit ?? null,
3367
3430
  sort: context.sort || null,
3368
3431
  page: context.page ?? null,
@@ -3392,30 +3455,23 @@ async function generateRuntimeProfileCard(context = {}) {
3392
3455
  worldId: context.worldId || null,
3393
3456
  agentId: resolvedContext.agentId || null,
3394
3457
  query: context.query ?? context.queryText ?? null,
3458
+ keywords: context.keywords || [],
3459
+ topics: context.topics || [],
3460
+ location: context.location || null,
3461
+ timeWindow: context.timeWindow || null,
3462
+ intent: context.intent || null,
3463
+ desiredInteraction: context.desiredInteraction || null,
3464
+ constraints: context.constraints || [],
3395
3465
  sort: context.sort || null,
3396
3466
  limit: context.limit ?? null,
3397
3467
  fetchImpl,
3398
3468
  logger,
3399
3469
  });
3400
3470
  },
3401
- fetchWorldCandidateFeed: async (context = {}) => {
3402
- const resolvedContext = await resolveBoundRuntimeContext(context);
3403
- return fetchWorldCandidateFeed({
3404
- cfg: resolvedContext.cfg || {},
3405
- accountId: resolvedContext.accountId || null,
3406
- runtimeConfig: resolvedContext.runtimeConfig || null,
3407
- worldId: context.worldId || null,
3408
- agentId: resolvedContext.agentId || null,
3409
- limit: context.limit ?? context.candidateLimit ?? null,
3410
- fetchImpl,
3411
- logger,
3412
- });
3413
- },
3414
3471
  resolveWorldSelection: (context = {}) => resolveWorldSelection(
3415
3472
  context.worldDirectory || {},
3416
3473
  context.selection ?? context.userChoice ?? null,
3417
3474
  ),
3418
- buildCandidateDeliverySummary,
3419
3475
  resolveWorldSelectionFlow: async (context = {}) => {
3420
3476
  const resolvedContext = await resolveBoundRuntimeContext(context);
3421
3477
  return resolveWorldSelectionFlow({
@@ -3464,6 +3520,32 @@ async function generateRuntimeProfileCard(context = {}) {
3464
3520
  });
3465
3521
  },
3466
3522
  },
3523
+ publicProfiles: {
3524
+ getPublicProfile: async (context = {}) => {
3525
+ const resolvedContext = await resolveBoundRuntimeContext(context);
3526
+ return getPublicProfile({
3527
+ cfg: resolvedContext.cfg || {},
3528
+ accountId: resolvedContext.accountId || null,
3529
+ runtimeConfig: resolvedContext.runtimeConfig || null,
3530
+ agentId: context.agentId || resolvedContext.agentId || null,
3531
+ viewerAgentId: resolvedContext.agentId || null,
3532
+ fetchImpl,
3533
+ logger,
3534
+ });
3535
+ },
3536
+ lookupPublicProfile: async (context = {}) => {
3537
+ const resolvedContext = await resolveBoundRuntimeContext(context);
3538
+ return lookupPublicProfile({
3539
+ cfg: resolvedContext.cfg || {},
3540
+ accountId: resolvedContext.accountId || null,
3541
+ runtimeConfig: resolvedContext.runtimeConfig || null,
3542
+ identity: context.identity || null,
3543
+ viewerAgentId: resolvedContext.agentId || null,
3544
+ fetchImpl,
3545
+ logger,
3546
+ });
3547
+ },
3548
+ },
3467
3549
  activity: {
3468
3550
  listWorldActivity: async (context = {}) => {
3469
3551
  const resolvedContext = await resolveBoundRuntimeContext(context);
@@ -3488,6 +3570,10 @@ async function generateRuntimeProfileCard(context = {}) {
3488
3570
  worldContextText: context.worldContextText || null,
3489
3571
  participantContextText: context.participantContextText || null,
3490
3572
  enabled: typeof context.enabled === 'boolean' ? context.enabled : true,
3573
+ visibility: context.visibility || null,
3574
+ identityMode: context.identityMode || null,
3575
+ joinPolicy: context.joinPolicy || null,
3576
+ approvalPolicy: context.approvalPolicy || null,
3491
3577
  fetchImpl,
3492
3578
  logger,
3493
3579
  });
@@ -3535,6 +3621,47 @@ async function generateRuntimeProfileCard(context = {}) {
3535
3621
  logger,
3536
3622
  });
3537
3623
  },
3624
+ inviteMember: async (context = {}) => {
3625
+ const resolvedContext = await resolveBoundRuntimeContext(context);
3626
+ return inviteModeratedWorldMember({
3627
+ cfg: resolvedContext.cfg || {},
3628
+ accountId: resolvedContext.accountId || null,
3629
+ runtimeConfig: resolvedContext.runtimeConfig || null,
3630
+ agentId: resolvedContext.agentId || null,
3631
+ worldId: context.worldId || null,
3632
+ targetAgentId: context.targetAgentId || null,
3633
+ identity: context.identity || null,
3634
+ inviteMessage: context.inviteMessage || null,
3635
+ fetchImpl,
3636
+ logger,
3637
+ });
3638
+ },
3639
+ revokeInvite: async (context = {}) => {
3640
+ const resolvedContext = await resolveBoundRuntimeContext(context);
3641
+ return revokeModeratedWorldInvite({
3642
+ cfg: resolvedContext.cfg || {},
3643
+ accountId: resolvedContext.accountId || null,
3644
+ runtimeConfig: resolvedContext.runtimeConfig || null,
3645
+ agentId: resolvedContext.agentId || null,
3646
+ worldId: context.worldId || null,
3647
+ targetAgentId: context.targetAgentId || null,
3648
+ fetchImpl,
3649
+ logger,
3650
+ });
3651
+ },
3652
+ listInvites: async (context = {}) => {
3653
+ const resolvedContext = await resolveBoundRuntimeContext(context);
3654
+ return fetchModeratedWorldInvites({
3655
+ cfg: resolvedContext.cfg || {},
3656
+ accountId: resolvedContext.accountId || null,
3657
+ runtimeConfig: resolvedContext.runtimeConfig || null,
3658
+ agentId: resolvedContext.agentId || null,
3659
+ worldId: context.worldId || null,
3660
+ status: context.status || 'invited',
3661
+ fetchImpl,
3662
+ logger,
3663
+ });
3664
+ },
3538
3665
  },
3539
3666
  membership: {
3540
3667
  listWorldMembers: async (context = {}) => {
@@ -3685,6 +3812,13 @@ async function generateRuntimeProfileCard(context = {}) {
3685
3812
  worldId: context.worldId || null,
3686
3813
  agentId: resolvedContext.agentId || null,
3687
3814
  query: context.query ?? context.queryText ?? null,
3815
+ keywords: context.keywords || [],
3816
+ topics: context.topics || [],
3817
+ location: context.location || null,
3818
+ timeWindow: context.timeWindow || null,
3819
+ intent: context.intent || null,
3820
+ desiredInteraction: context.desiredInteraction || null,
3821
+ constraints: context.constraints || [],
3688
3822
  limit: context.limit ?? null,
3689
3823
  sort: context.sort || null,
3690
3824
  page: context.page ?? null,
@@ -3714,27 +3848,20 @@ async function generateRuntimeProfileCard(context = {}) {
3714
3848
  worldId: context.worldId || null,
3715
3849
  agentId: resolvedContext.agentId || null,
3716
3850
  query: context.query ?? context.queryText ?? null,
3851
+ keywords: context.keywords || [],
3852
+ topics: context.topics || [],
3853
+ location: context.location || null,
3854
+ timeWindow: context.timeWindow || null,
3855
+ intent: context.intent || null,
3856
+ desiredInteraction: context.desiredInteraction || null,
3857
+ constraints: context.constraints || [],
3717
3858
  sort: context.sort || null,
3718
3859
  limit: context.limit ?? null,
3719
3860
  fetchImpl,
3720
3861
  logger,
3721
3862
  });
3722
3863
  },
3723
- fetchWorldCandidateFeed: async (context = {}) => {
3724
- const resolvedContext = await resolveBoundRuntimeContext(context);
3725
- return fetchWorldCandidateFeed({
3726
- cfg: resolvedContext.cfg || {},
3727
- accountId: resolvedContext.accountId || null,
3728
- runtimeConfig: resolvedContext.runtimeConfig || null,
3729
- worldId: context.worldId || null,
3730
- agentId: resolvedContext.agentId || null,
3731
- limit: context.limit ?? context.candidateLimit ?? null,
3732
- fetchImpl,
3733
- logger,
3734
- });
3735
- },
3736
3864
  resolveWorldSelection,
3737
- buildCandidateDeliverySummary,
3738
3865
  resolveWorldSelectionFlow: async (context = {}) => {
3739
3866
  const resolvedContext = await resolveBoundRuntimeContext(context);
3740
3867
  return resolveWorldSelectionFlow({
@@ -3748,6 +3875,32 @@ async function generateRuntimeProfileCard(context = {}) {
3748
3875
  logger,
3749
3876
  });
3750
3877
  },
3878
+ publicProfiles: {
3879
+ getPublicProfile: async (context = {}) => {
3880
+ const resolvedContext = await resolveBoundRuntimeContext(context);
3881
+ return getPublicProfile({
3882
+ cfg: resolvedContext.cfg || {},
3883
+ accountId: resolvedContext.accountId || null,
3884
+ runtimeConfig: resolvedContext.runtimeConfig || null,
3885
+ agentId: context.agentId || resolvedContext.agentId || null,
3886
+ viewerAgentId: resolvedContext.agentId || null,
3887
+ fetchImpl,
3888
+ logger,
3889
+ });
3890
+ },
3891
+ lookupPublicProfile: async (context = {}) => {
3892
+ const resolvedContext = await resolveBoundRuntimeContext(context);
3893
+ return lookupPublicProfile({
3894
+ cfg: resolvedContext.cfg || {},
3895
+ accountId: resolvedContext.accountId || null,
3896
+ runtimeConfig: resolvedContext.runtimeConfig || null,
3897
+ identity: context.identity || null,
3898
+ viewerAgentId: resolvedContext.agentId || null,
3899
+ fetchImpl,
3900
+ logger,
3901
+ });
3902
+ },
3903
+ },
3751
3904
  subscriptions: {
3752
3905
  listSubscriptions: async (context = {}) => {
3753
3906
  const resolvedContext = await resolveBoundRuntimeContext(context);
@@ -3832,6 +3985,10 @@ async function generateRuntimeProfileCard(context = {}) {
3832
3985
  worldContextText: context.worldContextText || null,
3833
3986
  participantContextText: context.participantContextText || null,
3834
3987
  enabled: typeof context.enabled === 'boolean' ? context.enabled : true,
3988
+ visibility: context.visibility || null,
3989
+ identityMode: context.identityMode || null,
3990
+ joinPolicy: context.joinPolicy || null,
3991
+ approvalPolicy: context.approvalPolicy || null,
3835
3992
  fetchImpl,
3836
3993
  logger,
3837
3994
  });
@@ -3879,6 +4036,47 @@ async function generateRuntimeProfileCard(context = {}) {
3879
4036
  logger,
3880
4037
  });
3881
4038
  },
4039
+ inviteMember: async (context = {}) => {
4040
+ const resolvedContext = await resolveBoundRuntimeContext(context);
4041
+ return inviteModeratedWorldMember({
4042
+ cfg: resolvedContext.cfg || {},
4043
+ accountId: resolvedContext.accountId || null,
4044
+ runtimeConfig: resolvedContext.runtimeConfig || null,
4045
+ agentId: resolvedContext.agentId || null,
4046
+ worldId: context.worldId || null,
4047
+ targetAgentId: context.targetAgentId || null,
4048
+ identity: context.identity || null,
4049
+ inviteMessage: context.inviteMessage || null,
4050
+ fetchImpl,
4051
+ logger,
4052
+ });
4053
+ },
4054
+ revokeInvite: async (context = {}) => {
4055
+ const resolvedContext = await resolveBoundRuntimeContext(context);
4056
+ return revokeModeratedWorldInvite({
4057
+ cfg: resolvedContext.cfg || {},
4058
+ accountId: resolvedContext.accountId || null,
4059
+ runtimeConfig: resolvedContext.runtimeConfig || null,
4060
+ agentId: resolvedContext.agentId || null,
4061
+ worldId: context.worldId || null,
4062
+ targetAgentId: context.targetAgentId || null,
4063
+ fetchImpl,
4064
+ logger,
4065
+ });
4066
+ },
4067
+ listInvites: async (context = {}) => {
4068
+ const resolvedContext = await resolveBoundRuntimeContext(context);
4069
+ return fetchModeratedWorldInvites({
4070
+ cfg: resolvedContext.cfg || {},
4071
+ accountId: resolvedContext.accountId || null,
4072
+ runtimeConfig: resolvedContext.runtimeConfig || null,
4073
+ agentId: resolvedContext.agentId || null,
4074
+ worldId: context.worldId || null,
4075
+ status: context.status || 'invited',
4076
+ fetchImpl,
4077
+ logger,
4078
+ });
4079
+ },
3882
4080
  },
3883
4081
  membership: {
3884
4082
  listWorldMembers: async (context = {}) => {
@@ -647,10 +647,7 @@ export function resolveClaworldManagedRuntimeOptions({
647
647
  const name = normalizeText(overrides.name, normalizeText(existingBackup.name, displayName));
648
648
  const existingRegistrationDisplayName = normalizeRegistrationDisplayName(
649
649
  existingAccount?.registration?.displayName,
650
- normalizeRegistrationDisplayName(
651
- existingAccount?.localAgent?.displayName,
652
- normalizeRegistrationDisplayName(existingBackup.registrationDisplayName, null),
653
- ),
650
+ normalizeRegistrationDisplayName(existingBackup.registrationDisplayName, null),
654
651
  );
655
652
  const registrationDisplayName = appToken && !explicitRegistrationDisplayName
656
653
  ? null
@@ -409,6 +409,10 @@ export function inferManageWorldAction(params = {}) {
409
409
  normalizeText(params.worldContextText, null)
410
410
  || normalizeText(params.displayName, null)
411
411
  || normalizeObject(params.broadcast, null)
412
+ || normalizeText(params.visibility, null)
413
+ || normalizeText(params.identityMode, null)
414
+ || normalizeText(params.joinPolicy, null)
415
+ || normalizeText(params.approvalPolicy, null)
412
416
  ) {
413
417
  return 'update_context';
414
418
  }