@xfxstudio/claworld 2026.4.22-testing.5 → 2026.4.22-testing.6

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.22-testing.5",
11
+ "version": "2026.4.22-testing.6",
12
12
  "configSchema": {
13
13
  "type": "object",
14
14
  "additionalProperties": false,
@@ -50,7 +50,7 @@
50
50
  "world",
51
51
  "full"
52
52
  ],
53
- "description": "Legacy ignored field retained for backward-compatible config parsing."
53
+ "description": "Optional ignored profile selector. Current tool exposure is backend-defined."
54
54
  },
55
55
  "heartbeatSeconds": {
56
56
  "type": "integer",
@@ -128,12 +128,12 @@
128
128
  "agentId": {
129
129
  "type": "string",
130
130
  "minLength": 1,
131
- "description": "Legacy relay agent id hint. Canonical flow resolves the binding from appToken at runtime."
131
+ "description": "Optional relay agent id hint. The current flow resolves the binding from appToken at runtime."
132
132
  },
133
133
  "credentialToken": {
134
134
  "type": "string",
135
135
  "minLength": 1,
136
- "description": "Legacy alias for appToken."
136
+ "description": "Optional credential token for this account. appToken is the current field."
137
137
  },
138
138
  "defaultTargetAgentId": {
139
139
  "type": "string",
@@ -197,7 +197,7 @@
197
197
  "world",
198
198
  "full"
199
199
  ],
200
- "description": "Legacy ignored field retained for backward-compatible config parsing."
200
+ "description": "Optional ignored profile selector. Current tool exposure is backend-defined."
201
201
  },
202
202
  "heartbeatSeconds": {
203
203
  "type": "integer",
@@ -275,12 +275,12 @@
275
275
  "agentId": {
276
276
  "type": "string",
277
277
  "minLength": 1,
278
- "description": "Legacy relay agent id hint. Canonical flow resolves the binding from appToken at runtime."
278
+ "description": "Optional relay agent id hint. The current flow resolves the binding from appToken at runtime."
279
279
  },
280
280
  "credentialToken": {
281
281
  "type": "string",
282
282
  "minLength": 1,
283
- "description": "Legacy alias for appToken."
283
+ "description": "Optional credential token for this account. appToken is the current field."
284
284
  },
285
285
  "defaultTargetAgentId": {
286
286
  "type": "string",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xfxstudio/claworld",
3
- "version": "2026.4.22-testing.5",
3
+ "version": "2026.4.22-testing.6",
4
4
  "description": "Claworld channel plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -215,7 +215,7 @@ ANNOUNCE_SKIP
215
215
 
216
216
  常见下一步是 `claworld_get_world_detail`,但不是写死的唯一下一步。
217
217
 
218
- `claworld_list_worlds` 现在只是 compatibility browse alias。除非已有旧流程明确要求,否则优先用 `claworld_search_worlds`。
218
+ `claworld_list_worlds` 用于无关键词浏览 world。用户带有主题、意图、爱好、地点等关键词时,优先用 `claworld_search_worlds`。
219
219
 
220
220
  ## `claworld_get_world_detail`
221
221
 
@@ -121,6 +121,8 @@ export async function markAcceptedChatKickoffProgressWithDeps(deps, {
121
121
  turnId = null,
122
122
  deliveryId = null,
123
123
  conversationKey = null,
124
+ sessionKey = null,
125
+ localSessionKey = null,
124
126
  senderKickoffDeliveredAt = null,
125
127
  openerAcceptedAt = null,
126
128
  openerDeliveredAt = null,
@@ -141,6 +143,12 @@ export async function markAcceptedChatKickoffProgressWithDeps(deps, {
141
143
  ...(normalizeOptionalText(turnId) ? { turnId: normalizeOptionalText(turnId) } : {}),
142
144
  ...(normalizeOptionalText(deliveryId) ? { deliveryId: normalizeOptionalText(deliveryId) } : {}),
143
145
  ...(normalizeOptionalText(conversationKey) ? { conversationKey: normalizeOptionalText(conversationKey) } : {}),
146
+ ...(normalizeOptionalText(sessionKey) ? { sessionKey: normalizeOptionalText(sessionKey) } : {}),
147
+ ...(normalizeOptionalText(localSessionKey)
148
+ ? { localSessionKey: normalizeOptionalText(localSessionKey) }
149
+ : normalizeOptionalText(sessionKey)
150
+ ? { localSessionKey: normalizeOptionalText(sessionKey) }
151
+ : {}),
144
152
  ...(normalizeOptionalText(senderKickoffDeliveredAt)
145
153
  ? {
146
154
  senderKickoffDeliveredAt: normalizeOptionalText(senderKickoffDeliveredAt),
@@ -40,12 +40,12 @@ export const MANUAL_RELAY_BINDING_SCHEMA = {
40
40
  agentId: {
41
41
  type: 'string',
42
42
  minLength: 1,
43
- description: 'Legacy relay agent id hint. Canonical flow resolves the binding from appToken at runtime.',
43
+ description: 'Optional relay agent id hint. The current flow resolves the binding from appToken at runtime.',
44
44
  },
45
45
  credentialToken: {
46
46
  type: 'string',
47
47
  minLength: 1,
48
- description: 'Legacy alias for appToken.',
48
+ description: 'Optional credential token for this account. appToken is the current field.',
49
49
  },
50
50
  defaultTargetAgentId: {
51
51
  type: 'string',
@@ -85,7 +85,7 @@ const SINGLE_ACCOUNT_PROPERTIES = {
85
85
  toolProfile: {
86
86
  type: 'string',
87
87
  enum: ['minimal', 'default', 'world', 'full'],
88
- description: 'Legacy ignored field retained for backward-compatible config parsing.',
88
+ description: 'Optional ignored profile selector. Current tool exposure is backend-defined.',
89
89
  },
90
90
  heartbeatSeconds: {
91
91
  type: 'integer',
@@ -203,7 +203,6 @@ function buildRegisteredTools(api, plugin) {
203
203
  'This is the main public discovery surface for worlds.',
204
204
  'Leave query empty to browse by hot or latest; provide a query to search by free-form intent such as hobby, location, or relationship goal.',
205
205
  'Expected behavior: returns paginated world summaries plus structured follow-up actions for detail and join.',
206
- 'claworld_list_worlds is only the compatibility browse alias for the empty-query branch.',
207
206
  ],
208
207
  examples: [
209
208
  {
@@ -278,12 +277,12 @@ function buildRegisteredTools(api, plugin) {
278
277
  {
279
278
  name: 'claworld_list_worlds',
280
279
  label: 'Claworld List Worlds',
281
- description: 'Compatibility browse alias for the search_worlds browse branch. Prefer claworld_search_worlds for all new world discovery flows.',
280
+ description: 'Browse worlds without a query. Use claworld_search_worlds when the user supplies topic, intent, hobby, location, or other keywords.',
282
281
  metadata: buildToolMetadata({
283
282
  category: 'world_discovery',
284
283
  usageNotes: [
285
- 'Compatibility-only wrapper around claworld_search_worlds with an empty query.',
286
- 'Prefer claworld_search_worlds unless an existing workflow explicitly asks for list_worlds.',
284
+ 'This tool returns the no-query world browse result.',
285
+ 'Use claworld_search_worlds when the user supplies topic, intent, hobby, location, or other keywords.',
287
286
  ],
288
287
  examples: [
289
288
  {
@@ -683,6 +683,7 @@ export class ClaworldRelayClient extends EventEmitter {
683
683
  const cleanup = () => {
684
684
  if (timeout) clearTimeout(timeout);
685
685
  this.off('reply.accepted', onReplyAccepted);
686
+ this.off('command.accepted', onCommandAccepted);
686
687
  this.off('disconnect', onDisconnect);
687
688
  this.off('close', onDisconnect);
688
689
  };
@@ -707,6 +708,20 @@ export class ClaworldRelayClient extends EventEmitter {
707
708
  settleResolve(message);
708
709
  };
709
710
 
711
+ const onCommandAccepted = (message = {}) => {
712
+ const command = message?.data?.command && typeof message.data.command === 'object'
713
+ ? message.data.command
714
+ : {};
715
+ if (normalizeOptionalText(command.name) !== 'delivery.reply.requested') return;
716
+ const commandDeliveryId = [
717
+ command.deliveryId,
718
+ command.aggregateId,
719
+ command.partitionKey,
720
+ ].map((value) => normalizeOptionalText(value)).find(Boolean) || null;
721
+ if (commandDeliveryId !== normalizedDeliveryId) return;
722
+ settleResolve(message);
723
+ };
724
+
710
725
  const onDisconnect = (info = {}) => {
711
726
  settleReject(createRuntimeBoundaryError({
712
727
  code: 'relay_reply_ack_disconnected',
@@ -725,6 +740,7 @@ export class ClaworldRelayClient extends EventEmitter {
725
740
  };
726
741
 
727
742
  this.on('reply.accepted', onReplyAccepted);
743
+ this.on('command.accepted', onCommandAccepted);
728
744
  this.on('disconnect', onDisconnect);
729
745
  this.on('close', onDisconnect);
730
746
 
@@ -589,7 +589,12 @@ function projectToolWorldBroadcastFailureItem(item = {}) {
589
589
  export function projectToolWorldBroadcastResponse(payload = {}, { accountId = null } = {}) {
590
590
  return {
591
591
  accountId: normalizeText(accountId, null),
592
+ accepted: payload.accepted === true,
592
593
  status: normalizeText(payload.status, null),
594
+ commandId: normalizeText(payload.commandId, null),
595
+ command: payload.command && typeof payload.command === 'object' && !Array.isArray(payload.command)
596
+ ? payload.command
597
+ : null,
593
598
  worldId: normalizeText(payload.worldId, null),
594
599
  senderAgentId: normalizeText(payload.senderAgentId, null),
595
600
  senderRole: projectWorldRole(payload.senderRole, null),
@@ -597,6 +602,7 @@ export function projectToolWorldBroadcastResponse(payload = {}, { accountId = nu
597
602
  excludeSelf: normalizeOptionalBoolean(payload.excludeSelf, null),
598
603
  eligibility: normalizeText(payload.eligibility, null),
599
604
  broadcastId: normalizeText(payload.broadcastId, null),
605
+ fanoutStatus: normalizeText(payload.fanoutStatus, null),
600
606
  totalTargets: normalizeOptionalInteger(payload.totalTargets, null),
601
607
  createdCount: normalizeOptionalInteger(payload.createdCount, null),
602
608
  failedCount: normalizeOptionalInteger(payload.failedCount, null),
@@ -167,7 +167,12 @@ function normalizeWorldBroadcastFailureItem(item = {}) {
167
167
 
168
168
  function normalizeWorldBroadcastResponse(payload = {}) {
169
169
  return {
170
+ accepted: payload.accepted === true,
170
171
  status: normalizeText(payload.status, null),
172
+ commandId: normalizeText(payload.commandId, null),
173
+ command: payload.command && typeof payload.command === 'object' && !Array.isArray(payload.command)
174
+ ? payload.command
175
+ : null,
171
176
  worldId: normalizeText(payload.worldId, null),
172
177
  senderAgentId: normalizeText(payload.senderAgentId, null),
173
178
  senderRole: normalizeWorldRole(payload.senderRole, null),
@@ -175,6 +180,7 @@ function normalizeWorldBroadcastResponse(payload = {}) {
175
180
  excludeSelf: normalizeOptionalBoolean(payload.excludeSelf, null),
176
181
  eligibility: normalizeText(payload.eligibility, null),
177
182
  broadcastId: normalizeText(payload.broadcastId, null),
183
+ fanoutStatus: normalizeText(payload.fanoutStatus, null),
178
184
  totalTargets: normalizeOptionalInteger(payload.totalTargets, null),
179
185
  createdCount: normalizeOptionalInteger(payload.createdCount, null),
180
186
  failedCount: normalizeOptionalInteger(payload.failedCount, null),
@@ -504,5 +510,9 @@ export async function broadcastModeratedWorld({
504
510
  });
505
511
  }
506
512
 
507
- return normalizeWorldBroadcastResponse(result.body);
513
+ return normalizeWorldBroadcastResponse({
514
+ ...result.body,
515
+ worldId: resolvedWorldId,
516
+ senderAgentId: resolvedAgentId,
517
+ });
508
518
  }