@xfxstudio/claworld 2026.4.29-testing.2 → 2026.4.29-testing.3
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/src/openclaw/plugin/register.js +174 -45
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -142,6 +142,33 @@ const CHAT_INBOX_FILTER_STATUSES = Object.freeze([
|
|
|
142
142
|
'kickoff_failed',
|
|
143
143
|
'ended',
|
|
144
144
|
]);
|
|
145
|
+
const CHAT_INBOX_FILTER_KEYS = Object.freeze([
|
|
146
|
+
'direction',
|
|
147
|
+
'mode',
|
|
148
|
+
'status',
|
|
149
|
+
'worldId',
|
|
150
|
+
'chatRequestId',
|
|
151
|
+
'conversationKey',
|
|
152
|
+
'localSessionKey',
|
|
153
|
+
'counterpartyAgentId',
|
|
154
|
+
]);
|
|
155
|
+
const CHAT_INBOX_FILTER_KEY_SET = new Set(CHAT_INBOX_FILTER_KEYS);
|
|
156
|
+
const MANAGE_CONVERSATION_REQUEST_ONLY_QUERY_FIELDS = Object.freeze([
|
|
157
|
+
'displayName',
|
|
158
|
+
'agentCode',
|
|
159
|
+
'openingMessage',
|
|
160
|
+
]);
|
|
161
|
+
const MANAGE_CONVERSATION_FILTER_ONLY_TOP_LEVEL_FIELDS = Object.freeze([
|
|
162
|
+
'mode',
|
|
163
|
+
'status',
|
|
164
|
+
'worldId',
|
|
165
|
+
'counterpartyAgentId',
|
|
166
|
+
]);
|
|
167
|
+
const MANAGE_CONVERSATION_GET_STATE_TARGET_FIELDS = Object.freeze([
|
|
168
|
+
'chatRequestId',
|
|
169
|
+
'conversationKey',
|
|
170
|
+
'localSessionKey',
|
|
171
|
+
]);
|
|
145
172
|
|
|
146
173
|
const TERMINAL_ACCOUNT_ACTIONS = Object.freeze([
|
|
147
174
|
'view_account',
|
|
@@ -292,6 +319,117 @@ function normalizeChatInboxListFiltersInput(params = {}) {
|
|
|
292
319
|
);
|
|
293
320
|
}
|
|
294
321
|
|
|
322
|
+
function hasProvidedToolParam(params = {}, fieldId) {
|
|
323
|
+
if (!params || typeof params !== 'object') return false;
|
|
324
|
+
if (!Object.prototype.hasOwnProperty.call(params, fieldId)) return false;
|
|
325
|
+
const value = params[fieldId];
|
|
326
|
+
if (typeof value === 'string') return normalizeText(value, null) != null;
|
|
327
|
+
return value != null;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function buildChatInboxFiltersParam({ description, worldIdProperty } = {}) {
|
|
331
|
+
return objectParam({
|
|
332
|
+
description,
|
|
333
|
+
additionalProperties: false,
|
|
334
|
+
properties: {
|
|
335
|
+
direction: stringParam({
|
|
336
|
+
description: 'Filter from the current account perspective.',
|
|
337
|
+
enumValues: CHAT_INBOX_FILTER_DIRECTIONS,
|
|
338
|
+
examples: ['outbound'],
|
|
339
|
+
}),
|
|
340
|
+
mode: stringParam({
|
|
341
|
+
description: 'Filter to direct or world-scoped chat items.',
|
|
342
|
+
enumValues: CHAT_INBOX_FILTER_MODES,
|
|
343
|
+
examples: ['world'],
|
|
344
|
+
}),
|
|
345
|
+
status: stringParam({
|
|
346
|
+
description: 'Filter to pending or terminal requests, or to chats by current status.',
|
|
347
|
+
enumValues: CHAT_INBOX_FILTER_STATUSES,
|
|
348
|
+
examples: ['active'],
|
|
349
|
+
}),
|
|
350
|
+
worldId: worldIdProperty,
|
|
351
|
+
chatRequestId: stringParam({
|
|
352
|
+
description: 'Filter to one canonical chat request id.',
|
|
353
|
+
minLength: 1,
|
|
354
|
+
examples: ['req_demo_1'],
|
|
355
|
+
}),
|
|
356
|
+
conversationKey: stringParam({
|
|
357
|
+
description: 'Filter to one canonical conversation key.',
|
|
358
|
+
minLength: 1,
|
|
359
|
+
examples: ['pair:agt_alice::agt_moza:world:dating-demo-world'],
|
|
360
|
+
}),
|
|
361
|
+
localSessionKey: stringParam({
|
|
362
|
+
description: 'Filter to one local Claworld session reference for internal tracking, summaries, or orchestration only. Not a transport address for sending a user message to the peer.',
|
|
363
|
+
minLength: 1,
|
|
364
|
+
examples: ['conversation:pair:agt_alice::agt_moza:world:dating-demo-world'],
|
|
365
|
+
}),
|
|
366
|
+
counterpartyAgentId: stringParam({
|
|
367
|
+
description: 'Filter to one counterparty agentId.',
|
|
368
|
+
minLength: 1,
|
|
369
|
+
examples: ['agt_alice'],
|
|
370
|
+
}),
|
|
371
|
+
},
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function validateChatInboxFilterInput(filters = {}, action) {
|
|
376
|
+
const source = normalizeObject(filters, {}) || {};
|
|
377
|
+
for (const key of Object.keys(source)) {
|
|
378
|
+
if (CHAT_INBOX_FILTER_KEY_SET.has(key)) continue;
|
|
379
|
+
requireManageWorldField(`filters.${key}`, `filters.${key} is not supported for action=${action}`);
|
|
380
|
+
}
|
|
381
|
+
return source;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
function normalizeManageConversationInboxQuery(params = {}, action) {
|
|
385
|
+
const normalizedAction = normalizeTerminalConversationAction(action, 'list_related');
|
|
386
|
+
const filters = validateChatInboxFilterInput(params.filters, normalizedAction);
|
|
387
|
+
|
|
388
|
+
const requestOnlyField = MANAGE_CONVERSATION_REQUEST_ONLY_QUERY_FIELDS.find((fieldId) => hasProvidedToolParam(params, fieldId));
|
|
389
|
+
if (requestOnlyField) {
|
|
390
|
+
requireManageWorldField(requestOnlyField, `${requestOnlyField} is only supported for action=request`);
|
|
391
|
+
}
|
|
392
|
+
if (hasProvidedToolParam(params, 'limit')) {
|
|
393
|
+
requireManageWorldField('limit', `limit is not supported for action=${normalizedAction}`);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const filterOnlyField = MANAGE_CONVERSATION_FILTER_ONLY_TOP_LEVEL_FIELDS.find((fieldId) => hasProvidedToolParam(params, fieldId));
|
|
397
|
+
if (filterOnlyField) {
|
|
398
|
+
requireManageWorldField(
|
|
399
|
+
filterOnlyField,
|
|
400
|
+
`${filterOnlyField} must be passed as filters.${filterOnlyField} for action=${normalizedAction}`,
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (normalizedAction !== 'get_state') {
|
|
405
|
+
const getStateOnlyField = MANAGE_CONVERSATION_GET_STATE_TARGET_FIELDS.find((fieldId) => hasProvidedToolParam(params, fieldId));
|
|
406
|
+
if (getStateOnlyField) {
|
|
407
|
+
requireManageWorldField(
|
|
408
|
+
getStateOnlyField,
|
|
409
|
+
`${getStateOnlyField} must be passed as filters.${getStateOnlyField} for action=${normalizedAction}`,
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const mergedFilters = {
|
|
415
|
+
...filters,
|
|
416
|
+
...(!Object.prototype.hasOwnProperty.call(filters, 'direction') && hasProvidedToolParam(params, 'direction')
|
|
417
|
+
? { direction: params.direction }
|
|
418
|
+
: {}),
|
|
419
|
+
...(normalizedAction === 'get_state'
|
|
420
|
+
? Object.fromEntries(
|
|
421
|
+
MANAGE_CONVERSATION_GET_STATE_TARGET_FIELDS
|
|
422
|
+
.filter((fieldId) => (
|
|
423
|
+
!Object.prototype.hasOwnProperty.call(filters, fieldId)
|
|
424
|
+
&& hasProvidedToolParam(params, fieldId)
|
|
425
|
+
))
|
|
426
|
+
.map((fieldId) => [fieldId, params[fieldId]]),
|
|
427
|
+
)
|
|
428
|
+
: {}),
|
|
429
|
+
};
|
|
430
|
+
return normalizeChatInboxListFiltersInput({ filters: mergedFilters });
|
|
431
|
+
}
|
|
432
|
+
|
|
295
433
|
function parseToolResultPayload(result = null) {
|
|
296
434
|
const text = result?.content?.[0]?.text;
|
|
297
435
|
if (typeof text !== 'string') return null;
|
|
@@ -924,10 +1062,27 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
924
1062
|
agentCode: stringParam({ description: 'Target public agent code for request.', minLength: 1 }),
|
|
925
1063
|
openingMessage: stringParam({ description: 'Request/re-engagement kickoff message.', minLength: 1 }),
|
|
926
1064
|
worldId: worldIdProperty,
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
1065
|
+
direction: stringParam({
|
|
1066
|
+
description: 'Top-level alias for filters.direction on action=list_related/get_state.',
|
|
1067
|
+
enumValues: CHAT_INBOX_FILTER_DIRECTIONS,
|
|
1068
|
+
examples: ['outbound'],
|
|
1069
|
+
}),
|
|
1070
|
+
filters: buildChatInboxFiltersParam({
|
|
1071
|
+
description: 'Inbox filters for action=list_related/get_state.',
|
|
1072
|
+
worldIdProperty,
|
|
1073
|
+
}),
|
|
1074
|
+
chatRequestId: stringParam({
|
|
1075
|
+
description: 'Request id for action=accept/reject, or a top-level get_state convenience target that normalizes to filters.chatRequestId.',
|
|
1076
|
+
minLength: 1,
|
|
1077
|
+
}),
|
|
1078
|
+
conversationKey: stringParam({
|
|
1079
|
+
description: 'Conversation key for action=close, or a top-level get_state convenience target that normalizes to filters.conversationKey.',
|
|
1080
|
+
minLength: 1,
|
|
1081
|
+
}),
|
|
1082
|
+
localSessionKey: stringParam({
|
|
1083
|
+
description: 'Local conversation session key for action=close, or a top-level get_state convenience target that normalizes to filters.localSessionKey.',
|
|
1084
|
+
minLength: 1,
|
|
1085
|
+
}),
|
|
931
1086
|
},
|
|
932
1087
|
}),
|
|
933
1088
|
async execute(toolCallId, params = {}) {
|
|
@@ -939,10 +1094,19 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
939
1094
|
});
|
|
940
1095
|
return rewriteToolResultName(result, manageConversationsTool, action);
|
|
941
1096
|
}
|
|
942
|
-
if (
|
|
1097
|
+
if (action === 'list_related' || action === 'get_state') {
|
|
1098
|
+
const filters = normalizeManageConversationInboxQuery(params, action);
|
|
943
1099
|
const result = await requireTerminalTool(internalTools, 'claworld_chat_inbox').execute(toolCallId, {
|
|
944
1100
|
...params,
|
|
945
|
-
action:
|
|
1101
|
+
action: 'list',
|
|
1102
|
+
...(Object.keys(filters).length > 0 ? { filters } : {}),
|
|
1103
|
+
});
|
|
1104
|
+
return rewriteToolResultName(result, manageConversationsTool, action);
|
|
1105
|
+
}
|
|
1106
|
+
if (action === 'accept' || action === 'reject') {
|
|
1107
|
+
const result = await requireTerminalTool(internalTools, 'claworld_chat_inbox').execute(toolCallId, {
|
|
1108
|
+
...params,
|
|
1109
|
+
action,
|
|
946
1110
|
});
|
|
947
1111
|
return rewriteToolResultName(result, manageConversationsTool, action);
|
|
948
1112
|
}
|
|
@@ -1690,45 +1854,10 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1690
1854
|
examples: ['list', 'accept', 'reject'],
|
|
1691
1855
|
}),
|
|
1692
1856
|
filters: objectParam({
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
enumValues: CHAT_INBOX_FILTER_DIRECTIONS,
|
|
1698
|
-
examples: ['outbound'],
|
|
1699
|
-
}),
|
|
1700
|
-
mode: stringParam({
|
|
1701
|
-
description: 'Filter to direct or world-scoped chat items.',
|
|
1702
|
-
enumValues: CHAT_INBOX_FILTER_MODES,
|
|
1703
|
-
examples: ['world'],
|
|
1704
|
-
}),
|
|
1705
|
-
status: stringParam({
|
|
1706
|
-
description: 'Filter to pending or terminal requests, or to chats by current status.',
|
|
1707
|
-
enumValues: CHAT_INBOX_FILTER_STATUSES,
|
|
1708
|
-
examples: ['active'],
|
|
1709
|
-
}),
|
|
1710
|
-
worldId: worldIdProperty,
|
|
1711
|
-
chatRequestId: stringParam({
|
|
1712
|
-
description: 'Filter to one canonical chat request id.',
|
|
1713
|
-
minLength: 1,
|
|
1714
|
-
examples: ['req_demo_1'],
|
|
1715
|
-
}),
|
|
1716
|
-
conversationKey: stringParam({
|
|
1717
|
-
description: 'Filter to one canonical conversation key.',
|
|
1718
|
-
minLength: 1,
|
|
1719
|
-
examples: ['pair:agt_alice::agt_moza:world:dating-demo-world'],
|
|
1720
|
-
}),
|
|
1721
|
-
localSessionKey: stringParam({
|
|
1722
|
-
description: 'Filter to one local Claworld session reference for internal tracking, summaries, or orchestration only. Not a transport address for sending a user message to the peer.',
|
|
1723
|
-
minLength: 1,
|
|
1724
|
-
examples: ['conversation:pair:agt_alice::agt_moza:world:dating-demo-world'],
|
|
1725
|
-
}),
|
|
1726
|
-
counterpartyAgentId: stringParam({
|
|
1727
|
-
description: 'Filter to one counterparty agentId.',
|
|
1728
|
-
minLength: 1,
|
|
1729
|
-
examples: ['agt_alice'],
|
|
1730
|
-
}),
|
|
1731
|
-
},
|
|
1857
|
+
...buildChatInboxFiltersParam({
|
|
1858
|
+
description: 'Optional list filters for query mode. Omit to review the full inbox across inbound and outbound items.',
|
|
1859
|
+
worldIdProperty,
|
|
1860
|
+
}),
|
|
1732
1861
|
}),
|
|
1733
1862
|
chatRequestId: stringParam({
|
|
1734
1863
|
description: 'Canonical chat request id returned by claworld_chat_inbox pendingRequests. Required for action=accept or action=reject.',
|