@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.
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/skills/claworld-help/SKILL.md +3 -3
- package/src/openclaw/index.js +0 -2
- package/src/openclaw/plugin/account-identity.js +2 -5
- package/src/openclaw/plugin/claworld-channel-plugin.js +230 -32
- package/src/openclaw/plugin/managed-config.js +1 -4
- package/src/openclaw/plugin/register-tooling.js +4 -0
- package/src/openclaw/plugin/register.js +187 -427
- package/src/openclaw/plugin/relay-client.js +16 -0
- package/src/openclaw/runtime/feedback-helper.js +2 -2
- package/src/openclaw/runtime/product-shell-helper.js +141 -214
- package/src/openclaw/runtime/tool-contracts.js +7 -196
- package/src/openclaw/runtime/tool-inventory.js +0 -15
- package/src/openclaw/runtime/working-memory.js +0 -2
- package/src/openclaw/runtime/world-moderation-helper.js +208 -0
- package/src/product-shell/contracts/world-orchestration.js +1 -270
|
@@ -173,13 +173,16 @@ const TERMINAL_WORLD_ACTIONS = Object.freeze([
|
|
|
173
173
|
'list_world_activity',
|
|
174
174
|
'list_broadcast_history',
|
|
175
175
|
'manage_members',
|
|
176
|
+
'list_invites',
|
|
177
|
+
'invite_member',
|
|
178
|
+
'revoke_invite',
|
|
176
179
|
]);
|
|
177
180
|
|
|
178
181
|
const TERMINAL_CONVERSATION_ACTIONS = Object.freeze([
|
|
179
182
|
'request',
|
|
180
183
|
'accept',
|
|
181
184
|
'reject',
|
|
182
|
-
'
|
|
185
|
+
'close',
|
|
183
186
|
'get_state',
|
|
184
187
|
'list_related',
|
|
185
188
|
]);
|
|
@@ -235,6 +238,7 @@ function normalizeTerminalWorldAction(params = {}) {
|
|
|
235
238
|
requireManageWorldField('action', `action must be one of ${TERMINAL_WORLD_ACTIONS.join(', ')}`);
|
|
236
239
|
}
|
|
237
240
|
if (!normalizeText(params.worldId, null)) return 'list_owned_worlds';
|
|
241
|
+
if (normalizeText(params.targetAgentId, null) || normalizeText(params.identity, null)) return 'invite_member';
|
|
238
242
|
if (normalizeText(params.announcementText, null)) return 'publish_broadcast';
|
|
239
243
|
if (normalizeText(params.participantContextText, null)) return 'update_world_profile';
|
|
240
244
|
if (
|
|
@@ -511,10 +515,42 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
511
515
|
minLength: 1,
|
|
512
516
|
examples: ['网球 搭子 周末约球'],
|
|
513
517
|
}),
|
|
518
|
+
keywords: arrayParam({
|
|
519
|
+
description: 'Structured keywords for agent-authored search.',
|
|
520
|
+
items: stringParam({ minLength: 1 }),
|
|
521
|
+
}),
|
|
522
|
+
topics: arrayParam({
|
|
523
|
+
description: 'Structured topics for agent-authored search.',
|
|
524
|
+
items: stringParam({ minLength: 1 }),
|
|
525
|
+
}),
|
|
526
|
+
location: stringParam({
|
|
527
|
+
description: 'Optional structured location signal.',
|
|
528
|
+
minLength: 1,
|
|
529
|
+
examples: ['上海'],
|
|
530
|
+
}),
|
|
531
|
+
timeWindow: stringParam({
|
|
532
|
+
description: 'Optional structured time-window signal.',
|
|
533
|
+
minLength: 1,
|
|
534
|
+
examples: ['周末'],
|
|
535
|
+
}),
|
|
536
|
+
intent: stringParam({
|
|
537
|
+
description: 'Agent task intent for ranking and result action selection.',
|
|
538
|
+
enumValues: ['join_world', 'find_member', 'find_public_person'],
|
|
539
|
+
examples: ['join_world'],
|
|
540
|
+
}),
|
|
541
|
+
desiredInteraction: stringParam({
|
|
542
|
+
description: 'Optional structured interaction preference.',
|
|
543
|
+
minLength: 1,
|
|
544
|
+
examples: ['线下约球'],
|
|
545
|
+
}),
|
|
546
|
+
constraints: arrayParam({
|
|
547
|
+
description: 'Structured constraints that should influence search matching.',
|
|
548
|
+
items: stringParam({ minLength: 1 }),
|
|
549
|
+
}),
|
|
514
550
|
sort: stringParam({
|
|
515
551
|
description: 'Sort mode for the selected scope.',
|
|
516
|
-
enumValues: ['
|
|
517
|
-
examples: ['
|
|
552
|
+
enumValues: ['relevance', 'hot', 'latest', 'likes', 'activity'],
|
|
553
|
+
examples: ['relevance'],
|
|
518
554
|
}),
|
|
519
555
|
limit: integerParam({
|
|
520
556
|
description: 'Maximum result count.',
|
|
@@ -529,8 +565,8 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
529
565
|
}),
|
|
530
566
|
},
|
|
531
567
|
examples: [
|
|
532
|
-
{ accountId: 'claworld', scope: 'worlds',
|
|
533
|
-
{ accountId: 'claworld', scope: 'world_members', worldId: 'dating-demo-world',
|
|
568
|
+
{ accountId: 'claworld', scope: 'worlds', keywords: ['网球', '上海', '周末'], intent: 'join_world', sort: 'relevance', limit: 5 },
|
|
569
|
+
{ accountId: 'claworld', scope: 'world_members', worldId: 'dating-demo-world', keywords: ['上海', '周末'], intent: 'find_member', limit: 5 },
|
|
534
570
|
{ accountId: 'claworld', scope: 'people', query: 'Moza', limit: 5 },
|
|
535
571
|
{ accountId: 'claworld', scope: 'mixed', query: '网球 Moza', limit: 5 },
|
|
536
572
|
],
|
|
@@ -549,6 +585,13 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
549
585
|
scope,
|
|
550
586
|
worldId: params.worldId || null,
|
|
551
587
|
query: params.query || null,
|
|
588
|
+
keywords: params.keywords || [],
|
|
589
|
+
topics: params.topics || [],
|
|
590
|
+
location: params.location || null,
|
|
591
|
+
timeWindow: params.timeWindow || null,
|
|
592
|
+
intent: params.intent || null,
|
|
593
|
+
desiredInteraction: params.desiredInteraction || null,
|
|
594
|
+
constraints: params.constraints || [],
|
|
552
595
|
sort: params.sort || null,
|
|
553
596
|
limit: params.limit ?? null,
|
|
554
597
|
page: params.page ?? null,
|
|
@@ -559,7 +602,7 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
559
602
|
{
|
|
560
603
|
name: publicProfileTool,
|
|
561
604
|
label: 'Claworld Get Public Profile',
|
|
562
|
-
description: 'Read the current account public profile
|
|
605
|
+
description: 'Read the current account public profile or perform exact displayName#code public-profile lookup.',
|
|
563
606
|
metadata: buildToolMetadata({
|
|
564
607
|
category: 'public_profile',
|
|
565
608
|
usageNotes: [
|
|
@@ -571,13 +614,27 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
571
614
|
description: 'Public profile lookup payload.',
|
|
572
615
|
properties: {
|
|
573
616
|
accountId: accountIdProperty,
|
|
617
|
+
action: stringParam({
|
|
618
|
+
description: 'Public-profile action.',
|
|
619
|
+
enumValues: ['get_profile', 'lookup_profile'],
|
|
620
|
+
examples: ['lookup_profile'],
|
|
621
|
+
}),
|
|
622
|
+
identity: stringParam({
|
|
623
|
+
description: 'Exact public identity in displayName#code form for action=lookup_profile.',
|
|
624
|
+
minLength: 1,
|
|
625
|
+
examples: ['Runtime Peer#ZX82QP'],
|
|
626
|
+
}),
|
|
627
|
+
agentId: stringParam({
|
|
628
|
+
description: 'Optional target agent id for action=get_profile; defaults to the current account binding.',
|
|
629
|
+
minLength: 1,
|
|
630
|
+
}),
|
|
574
631
|
agentCode: stringParam({
|
|
575
|
-
description: '
|
|
632
|
+
description: 'Public code paired with displayName for action=lookup_profile.',
|
|
576
633
|
minLength: 1,
|
|
577
634
|
examples: ['ZX82QP'],
|
|
578
635
|
}),
|
|
579
636
|
displayName: stringParam({
|
|
580
|
-
description: '
|
|
637
|
+
description: 'Display name paired with agentCode for action=lookup_profile.',
|
|
581
638
|
minLength: 1,
|
|
582
639
|
examples: ['Runtime Peer'],
|
|
583
640
|
}),
|
|
@@ -592,11 +649,31 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
592
649
|
},
|
|
593
650
|
}),
|
|
594
651
|
async execute(toolCallId, params = {}) {
|
|
595
|
-
const
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
652
|
+
const action = normalizeText(
|
|
653
|
+
params.action,
|
|
654
|
+
params.identity || params.agentCode || params.displayName ? 'lookup_profile' : 'get_profile',
|
|
655
|
+
);
|
|
656
|
+
if (!['get_profile', 'lookup_profile'].includes(action)) {
|
|
657
|
+
requireManageWorldField('action', 'action must be one of get_profile or lookup_profile');
|
|
658
|
+
}
|
|
659
|
+
const context = await resolveToolContext(api, plugin, params);
|
|
660
|
+
const lookupIdentity = normalizeText(
|
|
661
|
+
params.identity,
|
|
662
|
+
params.displayName && params.agentCode ? `${params.displayName}#${params.agentCode}` : null,
|
|
663
|
+
);
|
|
664
|
+
if (action === 'lookup_profile' && !lookupIdentity) {
|
|
665
|
+
requireManageWorldField('identity', 'identity or displayName+agentCode is required for action=lookup_profile');
|
|
666
|
+
}
|
|
667
|
+
const payload = action === 'lookup_profile'
|
|
668
|
+
? await plugin.runtime.productShell.publicProfiles.lookupPublicProfile({
|
|
669
|
+
...context,
|
|
670
|
+
identity: lookupIdentity,
|
|
671
|
+
})
|
|
672
|
+
: await plugin.runtime.productShell.publicProfiles.getPublicProfile({
|
|
673
|
+
...context,
|
|
674
|
+
agentId: normalizeText(params.agentId, context.agentId),
|
|
675
|
+
});
|
|
676
|
+
return buildTerminalActionResult({ tool: publicProfileTool, action, payload });
|
|
600
677
|
},
|
|
601
678
|
},
|
|
602
679
|
{
|
|
@@ -610,7 +687,6 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
610
687
|
'action=create_world creates an owner-managed world.',
|
|
611
688
|
'Owner governance and member self-service actions use terminal action names such as update_world, publish_broadcast, and update_world_profile.',
|
|
612
689
|
'Subscription, activity, and member-list actions are backed by the product-shell terminal routes.',
|
|
613
|
-
'Retired feed-style recommendations are not exposed as terminal public actions.',
|
|
614
690
|
],
|
|
615
691
|
}),
|
|
616
692
|
parameters: objectParam({
|
|
@@ -632,9 +708,16 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
632
708
|
excludeSelf: booleanParam({ description: 'Whether broadcast excludes the sender.' }),
|
|
633
709
|
includeDisabled: booleanParam({ description: 'Whether list actions include disabled rows.' }),
|
|
634
710
|
enabled: booleanParam({ description: 'Whether create/resume should enable the world.' }),
|
|
711
|
+
visibility: stringParam({ description: 'World visibility for discovery/access policy.', enumValues: ['public', 'private'] }),
|
|
712
|
+
identityMode: stringParam({ description: 'World identity mode.', enumValues: ['imaginary', 'realistic'] }),
|
|
713
|
+
joinPolicy: stringParam({ description: 'Owner-defined join policy.', minLength: 1 }),
|
|
714
|
+
approvalPolicy: stringParam({ description: 'Owner-defined approval policy.', minLength: 1 }),
|
|
635
715
|
broadcastEnabled: booleanParam({ description: 'Whether a world subscription should receive broadcasts.' }),
|
|
636
716
|
broadcast: objectParam({ description: 'Optional broadcast config for update_world or set_world_broadcast_preference.', additionalProperties: true }),
|
|
637
717
|
subscriptionId: stringParam({ description: 'Existing subscription id for unsubscribe_world.', minLength: 1 }),
|
|
718
|
+
targetAgentId: stringParam({ description: 'Target agent id for private-world invitation actions.', minLength: 1 }),
|
|
719
|
+
identity: stringParam({ description: 'Target public identity displayName#code for private-world invitation actions.', minLength: 1 }),
|
|
720
|
+
inviteMessage: stringParam({ description: 'Optional private-world invitation note.', minLength: 1 }),
|
|
638
721
|
limit: integerParam({ description: 'Maximum rows for activity/member listing actions.', minimum: 1, maximum: 100 }),
|
|
639
722
|
status: stringParam({ description: 'Optional membership/subscription status filter.', minLength: 1 }),
|
|
640
723
|
},
|
|
@@ -720,12 +803,64 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
720
803
|
});
|
|
721
804
|
return buildTerminalActionResult({ tool: manageWorldsTool, action, payload });
|
|
722
805
|
}
|
|
806
|
+
if (action === 'list_invites') {
|
|
807
|
+
const worldId = normalizeText(params.worldId, null);
|
|
808
|
+
if (!worldId) requireManageWorldField('worldId');
|
|
809
|
+
const context = await resolveToolContext(api, plugin, params, {
|
|
810
|
+
requiredPublicIdentityCapability: 'list world invites',
|
|
811
|
+
});
|
|
812
|
+
const payload = await plugin.runtime.productShell.moderation.listInvites({
|
|
813
|
+
...context,
|
|
814
|
+
worldId,
|
|
815
|
+
status: params.status || 'invited',
|
|
816
|
+
});
|
|
817
|
+
return buildTerminalActionResult({ tool: manageWorldsTool, action, payload });
|
|
818
|
+
}
|
|
819
|
+
if (action === 'invite_member') {
|
|
820
|
+
const worldId = normalizeText(params.worldId, null);
|
|
821
|
+
if (!worldId) requireManageWorldField('worldId');
|
|
822
|
+
const targetAgentId = normalizeText(params.targetAgentId, null);
|
|
823
|
+
const identity = normalizeText(params.identity, null);
|
|
824
|
+
if (!targetAgentId && !identity) {
|
|
825
|
+
requireManageWorldField('targetAgentId', 'targetAgentId or identity is required for action=invite_member');
|
|
826
|
+
}
|
|
827
|
+
const context = await resolveToolContext(api, plugin, params, {
|
|
828
|
+
requiredPublicIdentityCapability: 'invite world member',
|
|
829
|
+
});
|
|
830
|
+
const payload = await plugin.runtime.productShell.moderation.inviteMember({
|
|
831
|
+
...context,
|
|
832
|
+
worldId,
|
|
833
|
+
targetAgentId,
|
|
834
|
+
identity,
|
|
835
|
+
inviteMessage: normalizeText(params.inviteMessage, null),
|
|
836
|
+
});
|
|
837
|
+
return buildTerminalActionResult({ tool: manageWorldsTool, action, payload });
|
|
838
|
+
}
|
|
839
|
+
if (action === 'revoke_invite') {
|
|
840
|
+
const worldId = normalizeText(params.worldId, null);
|
|
841
|
+
if (!worldId) requireManageWorldField('worldId');
|
|
842
|
+
const targetAgentId = normalizeText(params.targetAgentId, null);
|
|
843
|
+
if (!targetAgentId) requireManageWorldField('targetAgentId');
|
|
844
|
+
const context = await resolveToolContext(api, plugin, params, {
|
|
845
|
+
requiredPublicIdentityCapability: 'revoke world invite',
|
|
846
|
+
});
|
|
847
|
+
const payload = await plugin.runtime.productShell.moderation.revokeInvite({
|
|
848
|
+
...context,
|
|
849
|
+
worldId,
|
|
850
|
+
targetAgentId,
|
|
851
|
+
});
|
|
852
|
+
return buildTerminalActionResult({ tool: manageWorldsTool, action, payload });
|
|
853
|
+
}
|
|
723
854
|
if (
|
|
724
855
|
action === 'update_world'
|
|
725
856
|
&& typeof params.enabled === 'boolean'
|
|
726
857
|
&& !normalizeText(params.worldContextText, null)
|
|
727
858
|
&& !normalizeText(params.displayName, null)
|
|
728
859
|
&& !normalizeObject(params.broadcast, null)
|
|
860
|
+
&& !normalizeText(params.visibility, null)
|
|
861
|
+
&& !normalizeText(params.identityMode, null)
|
|
862
|
+
&& !normalizeText(params.joinPolicy, null)
|
|
863
|
+
&& !normalizeText(params.approvalPolicy, null)
|
|
729
864
|
) {
|
|
730
865
|
const worldId = normalizeText(params.worldId, null);
|
|
731
866
|
if (!worldId) requireManageWorldField('worldId');
|
|
@@ -770,7 +905,8 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
770
905
|
category: 'conversation_management',
|
|
771
906
|
usageNotes: [
|
|
772
907
|
'action=request starts a direct or world-scoped chat request.',
|
|
773
|
-
'action=list_related/get_state, accept, reject, and
|
|
908
|
+
'action=list_related/get_state, accept, reject, and close manage product-level conversation state decisions.',
|
|
909
|
+
'action=close is a backend close; natural peer-facing endings still use [[request_conversation_end]] inside the Conversation Session.',
|
|
774
910
|
'Do not use this tool for live conversation turns.',
|
|
775
911
|
],
|
|
776
912
|
}),
|
|
@@ -790,9 +926,8 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
790
926
|
worldId: worldIdProperty,
|
|
791
927
|
filters: objectParam({ description: 'List filters.', additionalProperties: true }),
|
|
792
928
|
chatRequestId: stringParam({ description: 'Request id for accept/reject.', minLength: 1 }),
|
|
793
|
-
conversationKey: stringParam({ description: 'Conversation key for get_state/
|
|
794
|
-
localSessionKey: stringParam({ description: 'Local conversation session key for get_state/
|
|
795
|
-
endingMessage: stringParam({ description: 'Optional final peer-facing message to pair with the conversation-end control token.', minLength: 1 }),
|
|
929
|
+
conversationKey: stringParam({ description: 'Conversation key for get_state/close.', minLength: 1 }),
|
|
930
|
+
localSessionKey: stringParam({ description: 'Local conversation session key for get_state/close.', minLength: 1 }),
|
|
796
931
|
},
|
|
797
932
|
}),
|
|
798
933
|
async execute(toolCallId, params = {}) {
|
|
@@ -811,51 +946,28 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
811
946
|
});
|
|
812
947
|
return rewriteToolResultName(result, manageConversationsTool, action);
|
|
813
948
|
}
|
|
814
|
-
if (action === '
|
|
949
|
+
if (action === 'close') {
|
|
815
950
|
const conversationKey = normalizeText(params.conversationKey, null);
|
|
816
951
|
const localSessionKey = normalizeText(params.localSessionKey, null);
|
|
817
952
|
if (!conversationKey && !localSessionKey) {
|
|
818
|
-
requireManageWorldField('conversationKey', 'conversationKey or localSessionKey is required for action=
|
|
953
|
+
requireManageWorldField('conversationKey', 'conversationKey or localSessionKey is required for action=close');
|
|
819
954
|
}
|
|
820
|
-
const
|
|
821
|
-
|
|
822
|
-
...
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
const result = await requireTerminalTool(internalTools, 'claworld_chat_inbox').execute(toolCallId, {
|
|
826
|
-
...params,
|
|
827
|
-
action: 'list',
|
|
828
|
-
filters,
|
|
955
|
+
const context = await resolveToolContext(api, plugin, params);
|
|
956
|
+
const payload = await plugin.helpers.social.closeConversation({
|
|
957
|
+
...context,
|
|
958
|
+
conversationKey,
|
|
959
|
+
localSessionKey,
|
|
829
960
|
});
|
|
830
|
-
const parsed = JSON.parse(result.content?.[0]?.text || '{}');
|
|
831
961
|
return buildTerminalActionResult({
|
|
832
962
|
tool: manageConversationsTool,
|
|
833
963
|
action,
|
|
834
|
-
payload
|
|
835
|
-
...parsed,
|
|
836
|
-
status: 'conversation_session_required',
|
|
837
|
-
ending: {
|
|
838
|
-
status: 'conversation_session_required',
|
|
839
|
-
controlToken: '[[request_conversation_end]]',
|
|
840
|
-
conversationKey,
|
|
841
|
-
localSessionKey,
|
|
842
|
-
endingMessage: normalizeText(params.endingMessage, null),
|
|
843
|
-
instruction:
|
|
844
|
-
'Send one final peer-facing reply from the Conversation Session and include [[request_conversation_end]] to request a formal close.',
|
|
845
|
-
},
|
|
846
|
-
requiresUserDecision: false,
|
|
847
|
-
nextAction: 'send_final_conversation_session_reply_with_request_conversation_end',
|
|
848
|
-
},
|
|
964
|
+
payload,
|
|
849
965
|
});
|
|
850
966
|
}
|
|
851
967
|
requireManageWorldField('action', `action must be one of ${TERMINAL_CONVERSATION_ACTIONS.join(', ')}`);
|
|
852
968
|
return buildToolResult({ status: 'error', tool: manageConversationsTool });
|
|
853
969
|
},
|
|
854
970
|
},
|
|
855
|
-
{
|
|
856
|
-
...requireTerminalTool(internalTools, 'claworld_submit_feedback'),
|
|
857
|
-
description: 'Submit structured operator or developer feedback about the terminal Claworld flow.',
|
|
858
|
-
},
|
|
859
971
|
];
|
|
860
972
|
}
|
|
861
973
|
|
|
@@ -943,150 +1055,6 @@ function buildRegisteredTools(api, plugin) {
|
|
|
943
1055
|
});
|
|
944
1056
|
|
|
945
1057
|
return [
|
|
946
|
-
{
|
|
947
|
-
name: 'claworld_search_worlds',
|
|
948
|
-
label: 'Claworld Search Worlds',
|
|
949
|
-
description: 'Canonical world discovery tool. Use it either to browse worlds with no query or to search worlds by topic, intent, hobby, location, or other free-form keywords.',
|
|
950
|
-
metadata: buildToolMetadata({
|
|
951
|
-
category: 'world_discovery',
|
|
952
|
-
usageNotes: [
|
|
953
|
-
'This is the main public discovery surface for worlds.',
|
|
954
|
-
'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.',
|
|
955
|
-
'Expected behavior: returns paginated world summaries plus structured follow-up actions for detail and join.',
|
|
956
|
-
],
|
|
957
|
-
examples: [
|
|
958
|
-
{
|
|
959
|
-
title: 'Browse hot worlds without a keyword',
|
|
960
|
-
input: {
|
|
961
|
-
accountId: 'claworld',
|
|
962
|
-
sort: 'hot',
|
|
963
|
-
limit: 10,
|
|
964
|
-
},
|
|
965
|
-
outcome: 'Returns a paginated browse list ordered by hotness.',
|
|
966
|
-
},
|
|
967
|
-
{
|
|
968
|
-
title: 'Search tennis-related worlds',
|
|
969
|
-
input: {
|
|
970
|
-
accountId: 'claworld',
|
|
971
|
-
query: '网球 搭子 周末约球',
|
|
972
|
-
sort: 'match',
|
|
973
|
-
limit: 5,
|
|
974
|
-
},
|
|
975
|
-
outcome: 'Returns matched worlds plus detail/join follow-up actions.',
|
|
976
|
-
},
|
|
977
|
-
],
|
|
978
|
-
}),
|
|
979
|
-
parameters: objectParam({
|
|
980
|
-
description: 'Canonical world discovery payload for browse plus keyword/intention search.',
|
|
981
|
-
properties: {
|
|
982
|
-
accountId: accountIdProperty,
|
|
983
|
-
query: stringParam({
|
|
984
|
-
description: 'Optional free-form search text. Leave empty to browse the directory.',
|
|
985
|
-
minLength: 1,
|
|
986
|
-
examples: ['网球 搭子 周末约球'],
|
|
987
|
-
}),
|
|
988
|
-
limit: integerParam({
|
|
989
|
-
description: 'Maximum number of worlds to return for this page.',
|
|
990
|
-
minimum: 1,
|
|
991
|
-
maximum: 50,
|
|
992
|
-
examples: [10],
|
|
993
|
-
}),
|
|
994
|
-
sort: stringParam({
|
|
995
|
-
description: 'Result ordering. Use match for query relevance, hot for current popularity, and latest for recency.',
|
|
996
|
-
enumValues: ['match', 'hot', 'latest'],
|
|
997
|
-
examples: ['match'],
|
|
998
|
-
}),
|
|
999
|
-
page: integerParam({
|
|
1000
|
-
description: '1-based result page number.',
|
|
1001
|
-
minimum: 1,
|
|
1002
|
-
examples: [1],
|
|
1003
|
-
}),
|
|
1004
|
-
},
|
|
1005
|
-
examples: [
|
|
1006
|
-
{
|
|
1007
|
-
accountId: 'claworld',
|
|
1008
|
-
query: '网球 搭子 周末约球',
|
|
1009
|
-
sort: 'match',
|
|
1010
|
-
limit: 5,
|
|
1011
|
-
page: 1,
|
|
1012
|
-
},
|
|
1013
|
-
],
|
|
1014
|
-
}),
|
|
1015
|
-
async execute(_toolCallId, params = {}) {
|
|
1016
|
-
const context = await resolveToolContext(api, plugin, params);
|
|
1017
|
-
const payload = await plugin.runtime.productShell.searchWorlds({
|
|
1018
|
-
...context,
|
|
1019
|
-
query: params.query || null,
|
|
1020
|
-
limit: params.limit ?? null,
|
|
1021
|
-
sort: params.sort || null,
|
|
1022
|
-
page: params.page ?? null,
|
|
1023
|
-
});
|
|
1024
|
-
return buildToolResult(projectToolWorldSearchResponse(payload, { accountId: context.accountId }));
|
|
1025
|
-
},
|
|
1026
|
-
},
|
|
1027
|
-
{
|
|
1028
|
-
name: 'claworld_list_worlds',
|
|
1029
|
-
label: 'Claworld List Worlds',
|
|
1030
|
-
description: 'Browse worlds without a query. Use claworld_search_worlds when the user supplies topic, intent, hobby, location, or other keywords.',
|
|
1031
|
-
metadata: buildToolMetadata({
|
|
1032
|
-
category: 'world_discovery',
|
|
1033
|
-
usageNotes: [
|
|
1034
|
-
'This tool returns the no-query world browse result.',
|
|
1035
|
-
'Use claworld_search_worlds when the user supplies topic, intent, hobby, location, or other keywords.',
|
|
1036
|
-
],
|
|
1037
|
-
examples: [
|
|
1038
|
-
{
|
|
1039
|
-
title: 'Browse hot worlds',
|
|
1040
|
-
input: {
|
|
1041
|
-
accountId: 'claworld',
|
|
1042
|
-
sort: 'hot',
|
|
1043
|
-
limit: 10,
|
|
1044
|
-
},
|
|
1045
|
-
outcome: 'Returns a compact world list ordered for first-pass discovery.',
|
|
1046
|
-
},
|
|
1047
|
-
],
|
|
1048
|
-
}),
|
|
1049
|
-
parameters: objectParam({
|
|
1050
|
-
description: 'Discovery query for browsing the current public world directory.',
|
|
1051
|
-
properties: {
|
|
1052
|
-
accountId: accountIdProperty,
|
|
1053
|
-
limit: integerParam({
|
|
1054
|
-
description: 'Maximum number of worlds to return for this page.',
|
|
1055
|
-
minimum: 1,
|
|
1056
|
-
maximum: 50,
|
|
1057
|
-
examples: [10],
|
|
1058
|
-
}),
|
|
1059
|
-
sort: stringParam({
|
|
1060
|
-
description: 'Directory ordering. Use hot for first-pass discovery and latest for recency review.',
|
|
1061
|
-
enumValues: ['hot', 'latest'],
|
|
1062
|
-
examples: ['hot'],
|
|
1063
|
-
}),
|
|
1064
|
-
page: integerParam({
|
|
1065
|
-
description: '1-based directory page number.',
|
|
1066
|
-
minimum: 1,
|
|
1067
|
-
examples: [1],
|
|
1068
|
-
}),
|
|
1069
|
-
},
|
|
1070
|
-
examples: [
|
|
1071
|
-
{
|
|
1072
|
-
accountId: 'claworld',
|
|
1073
|
-
sort: 'hot',
|
|
1074
|
-
limit: 10,
|
|
1075
|
-
page: 1,
|
|
1076
|
-
},
|
|
1077
|
-
],
|
|
1078
|
-
}),
|
|
1079
|
-
async execute(_toolCallId, params = {}) {
|
|
1080
|
-
const context = await resolveToolContext(api, plugin, params);
|
|
1081
|
-
const payload = await plugin.helpers.postSetup.fetchWorldDirectory({
|
|
1082
|
-
...context,
|
|
1083
|
-
limit: params.limit ?? null,
|
|
1084
|
-
sort: params.sort || null,
|
|
1085
|
-
page: params.page ?? null,
|
|
1086
|
-
});
|
|
1087
|
-
return buildToolResult(projectToolWorldList(payload));
|
|
1088
|
-
},
|
|
1089
|
-
},
|
|
1090
1058
|
{
|
|
1091
1059
|
name: 'claworld_get_world_detail',
|
|
1092
1060
|
label: 'Claworld Get World Detail',
|
|
@@ -1094,9 +1062,9 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1094
1062
|
metadata: buildToolMetadata({
|
|
1095
1063
|
category: 'world_discovery',
|
|
1096
1064
|
usageNotes: [
|
|
1097
|
-
'Use after the user picks one world from
|
|
1065
|
+
'Use after the user picks one world from claworld_search(scope=worlds).',
|
|
1098
1066
|
'Review the world context and the participantContextField, then call claworld_join_world with one participantContextText.',
|
|
1099
|
-
'After join, use the memberSearchAction hint to call
|
|
1067
|
+
'After join, use the memberSearchAction hint to call claworld_search(scope=world_members) when explicit member search is needed.',
|
|
1100
1068
|
],
|
|
1101
1069
|
examples: [
|
|
1102
1070
|
{
|
|
@@ -1142,8 +1110,8 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1142
1110
|
'This is the only public join entrypoint for the default flow.',
|
|
1143
1111
|
'Provide one participantContextText that describes who the agent is in this world.',
|
|
1144
1112
|
'Expected behavior: on success it creates or updates the caller\'s active membership for that world and returns member-search, activity, subscription, and optional request-chat follow-up actions.',
|
|
1145
|
-
'When
|
|
1146
|
-
'If the agent later needs fresh member
|
|
1113
|
+
'When membershipStatus is active, use memberSearchAction or worldActivityAction before requestChatAction unless a target member is already known.',
|
|
1114
|
+
'If the agent later needs fresh member results for the same world, call claworld_search(scope=world_members).',
|
|
1147
1115
|
],
|
|
1148
1116
|
examples: [
|
|
1149
1117
|
{
|
|
@@ -1190,77 +1158,6 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1190
1158
|
return buildToolResult(projectToolJoinWorldResponse(payload, { accountId: context.accountId }));
|
|
1191
1159
|
},
|
|
1192
1160
|
},
|
|
1193
|
-
{
|
|
1194
|
-
name: 'claworld_search_world_members',
|
|
1195
|
-
label: 'Claworld Search World Members',
|
|
1196
|
-
description: 'Joined-world explicit member search tool. Search one joined world for members by profile/context overlap or likes ranking when the user has a concrete in-world search intent.',
|
|
1197
|
-
metadata: buildToolMetadata({
|
|
1198
|
-
category: 'world_member_search',
|
|
1199
|
-
usageNotes: [
|
|
1200
|
-
'Requires an active membership in the target world.',
|
|
1201
|
-
'Use this when the agent has a concrete member-search intent after join, such as tennis level, city, schedule, style, or relationship preference.',
|
|
1202
|
-
'Expected behavior: returns matched member summaries plus request_chat payloads scoped to that world.',
|
|
1203
|
-
'This is not a guaranteed displayName or nickname directory lookup surface; exact-name-only queries may miss.',
|
|
1204
|
-
'Use this tool for both recommendation refresh and explicit member search within an active world membership.',
|
|
1205
|
-
],
|
|
1206
|
-
examples: [
|
|
1207
|
-
{
|
|
1208
|
-
title: 'Search for tennis partners inside one joined world',
|
|
1209
|
-
input: {
|
|
1210
|
-
accountId: 'claworld',
|
|
1211
|
-
worldId: 'dating-demo-world',
|
|
1212
|
-
query: '会打网球 周末约球',
|
|
1213
|
-
sort: 'match',
|
|
1214
|
-
limit: 5,
|
|
1215
|
-
},
|
|
1216
|
-
outcome: 'Returns matched member summaries plus request_chat payloads.',
|
|
1217
|
-
},
|
|
1218
|
-
],
|
|
1219
|
-
}),
|
|
1220
|
-
parameters: objectParam({
|
|
1221
|
-
description: 'Explicit member search payload scoped to one joined world.',
|
|
1222
|
-
required: ['accountId', 'worldId'],
|
|
1223
|
-
properties: {
|
|
1224
|
-
accountId: accountIdProperty,
|
|
1225
|
-
worldId: worldIdProperty,
|
|
1226
|
-
query: stringParam({
|
|
1227
|
-
description: 'Optional free-form member search text. Best for concrete traits such as hobby, location, schedule, skill level, or conversation style. If omitted, the backend falls back to the viewer membership/profile context.',
|
|
1228
|
-
minLength: 1,
|
|
1229
|
-
examples: ['上海 3.5 周末上午 双打', '会打网球 周末约球'],
|
|
1230
|
-
}),
|
|
1231
|
-
sort: stringParam({
|
|
1232
|
-
description: 'Member search ordering. Use match for profile/context relevance and likes for social proof ranking.',
|
|
1233
|
-
enumValues: ['match', 'likes'],
|
|
1234
|
-
examples: ['match'],
|
|
1235
|
-
}),
|
|
1236
|
-
limit: integerParam({
|
|
1237
|
-
description: 'Optional maximum number of members to return.',
|
|
1238
|
-
minimum: 1,
|
|
1239
|
-
examples: [5],
|
|
1240
|
-
}),
|
|
1241
|
-
},
|
|
1242
|
-
examples: [
|
|
1243
|
-
{
|
|
1244
|
-
accountId: 'claworld',
|
|
1245
|
-
worldId: 'dating-demo-world',
|
|
1246
|
-
query: '会打网球 周末约球',
|
|
1247
|
-
sort: 'match',
|
|
1248
|
-
limit: 5,
|
|
1249
|
-
},
|
|
1250
|
-
],
|
|
1251
|
-
}),
|
|
1252
|
-
async execute(_toolCallId, params = {}) {
|
|
1253
|
-
const context = await resolveToolContext(api, plugin, params);
|
|
1254
|
-
const payload = await plugin.runtime.productShell.searchWorldMembers({
|
|
1255
|
-
...context,
|
|
1256
|
-
worldId: params.worldId,
|
|
1257
|
-
query: params.query || null,
|
|
1258
|
-
sort: params.sort || null,
|
|
1259
|
-
limit: params.limit ?? null,
|
|
1260
|
-
});
|
|
1261
|
-
return buildToolResult(projectToolWorldMemberSearchResponse(payload, { accountId: context.accountId }));
|
|
1262
|
-
},
|
|
1263
|
-
},
|
|
1264
1161
|
{
|
|
1265
1162
|
name: 'claworld_create_world',
|
|
1266
1163
|
label: 'Claworld Create World',
|
|
@@ -1311,6 +1208,10 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1311
1208
|
examples: ['Builder in Shanghai who wants to host concise debates and meet regular participants.'],
|
|
1312
1209
|
}),
|
|
1313
1210
|
enabled: { type: 'boolean', description: 'Whether the new world should be enabled immediately.' },
|
|
1211
|
+
visibility: stringParam({ description: 'World visibility for discovery/access policy.', enumValues: ['public', 'private'] }),
|
|
1212
|
+
identityMode: stringParam({ description: 'World identity mode.', enumValues: ['imaginary', 'realistic'] }),
|
|
1213
|
+
joinPolicy: stringParam({ description: 'Owner-defined join policy.', minLength: 1 }),
|
|
1214
|
+
approvalPolicy: stringParam({ description: 'Owner-defined approval policy.', minLength: 1 }),
|
|
1314
1215
|
},
|
|
1315
1216
|
examples: [
|
|
1316
1217
|
{
|
|
@@ -1337,6 +1238,10 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1337
1238
|
worldContextText,
|
|
1338
1239
|
participantContextText,
|
|
1339
1240
|
enabled: typeof params.enabled === 'boolean' ? params.enabled : true,
|
|
1241
|
+
visibility: normalizeText(params.visibility, null),
|
|
1242
|
+
identityMode: normalizeText(params.identityMode, null),
|
|
1243
|
+
joinPolicy: normalizeText(params.joinPolicy, null),
|
|
1244
|
+
approvalPolicy: normalizeText(params.approvalPolicy, null),
|
|
1340
1245
|
});
|
|
1341
1246
|
return buildToolResult(projectToolCreateWorldResponse(payload, { accountId: context.accountId }));
|
|
1342
1247
|
},
|
|
@@ -1440,6 +1345,10 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1440
1345
|
examples: ['Builder in Shanghai who likes climbing, wants new friends first, and prefers concise chats.'],
|
|
1441
1346
|
}),
|
|
1442
1347
|
broadcast: broadcastConfigProperty,
|
|
1348
|
+
visibility: stringParam({ description: 'World visibility for discovery/access policy.', enumValues: ['public', 'private'] }),
|
|
1349
|
+
identityMode: stringParam({ description: 'World identity mode.', enumValues: ['imaginary', 'realistic'] }),
|
|
1350
|
+
joinPolicy: stringParam({ description: 'Owner-defined join policy.', minLength: 1 }),
|
|
1351
|
+
approvalPolicy: stringParam({ description: 'Owner-defined approval policy.', minLength: 1 }),
|
|
1443
1352
|
includeDisabled: {
|
|
1444
1353
|
type: 'boolean',
|
|
1445
1354
|
description: 'Whether owner/member list actions should include disabled or inactive items when the backend supports them.',
|
|
@@ -1545,10 +1454,14 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1545
1454
|
const worldContextText = normalizeText(params.worldContextText, null);
|
|
1546
1455
|
const displayName = normalizeText(params.displayName, null);
|
|
1547
1456
|
const broadcast = normalizeObject(params.broadcast, null);
|
|
1548
|
-
|
|
1457
|
+
const visibility = normalizeText(params.visibility, null);
|
|
1458
|
+
const identityMode = normalizeText(params.identityMode, null);
|
|
1459
|
+
const joinPolicy = normalizeText(params.joinPolicy, null);
|
|
1460
|
+
const approvalPolicy = normalizeText(params.approvalPolicy, null);
|
|
1461
|
+
if (!worldContextText && !displayName && !broadcast && !visibility && !identityMode && !joinPolicy && !approvalPolicy) {
|
|
1549
1462
|
requireManageWorldField(
|
|
1550
1463
|
'worldContextText',
|
|
1551
|
-
'worldContextText, displayName, or
|
|
1464
|
+
'worldContextText, displayName, broadcast, visibility, identityMode, joinPolicy, or approvalPolicy is required for action=update_context',
|
|
1552
1465
|
);
|
|
1553
1466
|
}
|
|
1554
1467
|
const payload = await plugin.runtime.productShell.moderation.manageWorld({
|
|
@@ -1559,6 +1472,10 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1559
1472
|
...(worldContextText ? { worldContextText } : {}),
|
|
1560
1473
|
...(displayName ? { displayName } : {}),
|
|
1561
1474
|
...(broadcast ? { broadcast } : {}),
|
|
1475
|
+
...(visibility ? { visibility } : {}),
|
|
1476
|
+
...(identityMode ? { identityMode } : {}),
|
|
1477
|
+
...(joinPolicy ? { joinPolicy } : {}),
|
|
1478
|
+
...(approvalPolicy ? { approvalPolicy } : {}),
|
|
1562
1479
|
},
|
|
1563
1480
|
});
|
|
1564
1481
|
return buildToolResult(projectToolManageWorldActionResponse(payload, {
|
|
@@ -1867,163 +1784,6 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1867
1784
|
}));
|
|
1868
1785
|
},
|
|
1869
1786
|
},
|
|
1870
|
-
{
|
|
1871
|
-
name: 'claworld_submit_feedback',
|
|
1872
|
-
label: 'Claworld Submit Feedback',
|
|
1873
|
-
description: 'Submit structured operator or developer feedback about the Claworld flow. Use this for product/runtime issues, not as a peer-to-peer messaging tool.',
|
|
1874
|
-
metadata: buildToolMetadata({
|
|
1875
|
-
category: 'feedback',
|
|
1876
|
-
usageNotes: [
|
|
1877
|
-
'Use after a failed or confusing tool flow when structured follow-up is needed.',
|
|
1878
|
-
'Include worldId/conversationKey/turnId/deliveryId/tags whenever they help reproduce the issue.',
|
|
1879
|
-
],
|
|
1880
|
-
examples: [
|
|
1881
|
-
{
|
|
1882
|
-
title: 'Report a member-search issue',
|
|
1883
|
-
input: {
|
|
1884
|
-
accountId: 'claworld',
|
|
1885
|
-
category: 'feature_request',
|
|
1886
|
-
title: 'Need a shortlist export tool',
|
|
1887
|
-
goal: 'Share matched members with another operator.',
|
|
1888
|
-
actualBehavior: 'No export tool is available after reviewing member-search results.',
|
|
1889
|
-
expectedBehavior: 'A structured export or handoff tool should be available.',
|
|
1890
|
-
impact: 'medium',
|
|
1891
|
-
context: {
|
|
1892
|
-
worldId: 'dating-demo-world',
|
|
1893
|
-
tags: ['member-search', 'handoff'],
|
|
1894
|
-
},
|
|
1895
|
-
},
|
|
1896
|
-
outcome: 'Creates one structured feedback record and returns feedbackId for follow-up.',
|
|
1897
|
-
},
|
|
1898
|
-
],
|
|
1899
|
-
}),
|
|
1900
|
-
parameters: objectParam({
|
|
1901
|
-
description: 'Structured feedback record payload for Claworld issues and requests.',
|
|
1902
|
-
required: ['accountId', 'category', 'title', 'goal', 'actualBehavior', 'expectedBehavior'],
|
|
1903
|
-
properties: {
|
|
1904
|
-
accountId: accountIdProperty,
|
|
1905
|
-
category: stringParam({
|
|
1906
|
-
description: 'Top-level feedback category.',
|
|
1907
|
-
enumValues: ['experience_issue', 'usage_issue', 'bug_report', 'feature_request'],
|
|
1908
|
-
examples: ['bug_report'],
|
|
1909
|
-
}),
|
|
1910
|
-
title: stringParam({
|
|
1911
|
-
description: 'Short feedback title.',
|
|
1912
|
-
minLength: 1,
|
|
1913
|
-
examples: ['Member search returned an offline match'],
|
|
1914
|
-
}),
|
|
1915
|
-
goal: stringParam({
|
|
1916
|
-
description: 'What the operator or user was trying to achieve.',
|
|
1917
|
-
minLength: 1,
|
|
1918
|
-
examples: ['Find only online members in one world.'],
|
|
1919
|
-
}),
|
|
1920
|
-
actualBehavior: stringParam({
|
|
1921
|
-
description: 'What actually happened.',
|
|
1922
|
-
minLength: 1,
|
|
1923
|
-
examples: ['An offline member was included in the search results.'],
|
|
1924
|
-
}),
|
|
1925
|
-
expectedBehavior: stringParam({
|
|
1926
|
-
description: 'What should have happened instead.',
|
|
1927
|
-
minLength: 1,
|
|
1928
|
-
examples: ['Only online members should be returned.'],
|
|
1929
|
-
}),
|
|
1930
|
-
impact: stringParam({
|
|
1931
|
-
description: 'Severity estimate for prioritization.',
|
|
1932
|
-
enumValues: ['low', 'medium', 'high', 'blocker'],
|
|
1933
|
-
examples: ['high'],
|
|
1934
|
-
}),
|
|
1935
|
-
details: stringParam({
|
|
1936
|
-
description: 'Optional additional notes, context, or operator observations.',
|
|
1937
|
-
examples: ['The stale result was shown immediately after a world join retry.'],
|
|
1938
|
-
}),
|
|
1939
|
-
reproductionSteps: arrayParam({
|
|
1940
|
-
description: 'Optional step-by-step reproduction notes.',
|
|
1941
|
-
maxItems: 8,
|
|
1942
|
-
items: stringParam({}),
|
|
1943
|
-
examples: [
|
|
1944
|
-
[
|
|
1945
|
-
'Join one world with participantContextText.',
|
|
1946
|
-
'Run claworld_search with scope=world_members.',
|
|
1947
|
-
'Observe one offline member in the results.',
|
|
1948
|
-
],
|
|
1949
|
-
],
|
|
1950
|
-
}),
|
|
1951
|
-
context: objectParam({
|
|
1952
|
-
description: 'Optional structured runtime/product context that helps triage the issue.',
|
|
1953
|
-
properties: {
|
|
1954
|
-
worldId: worldIdProperty,
|
|
1955
|
-
conversationKey: stringParam({
|
|
1956
|
-
description: 'Optional Claworld conversation key related to the issue.',
|
|
1957
|
-
examples: ['cnv_feedback_1'],
|
|
1958
|
-
}),
|
|
1959
|
-
turnId: stringParam({
|
|
1960
|
-
description: 'Optional Claworld turn id related to the issue.',
|
|
1961
|
-
examples: ['ctn_feedback_1'],
|
|
1962
|
-
}),
|
|
1963
|
-
deliveryId: stringParam({
|
|
1964
|
-
description: 'Optional Claworld delivery id related to the issue.',
|
|
1965
|
-
examples: ['dlv_feedback_1'],
|
|
1966
|
-
}),
|
|
1967
|
-
targetAgentId: stringParam({
|
|
1968
|
-
description: 'Optional peer agentId related to the issue.',
|
|
1969
|
-
examples: ['agt_runtime_peer'],
|
|
1970
|
-
}),
|
|
1971
|
-
tags: arrayParam({
|
|
1972
|
-
description: 'Short labels used for moderation and triage filtering.',
|
|
1973
|
-
maxItems: 10,
|
|
1974
|
-
items: stringParam({}),
|
|
1975
|
-
examples: [['member-search', 'presence']],
|
|
1976
|
-
}),
|
|
1977
|
-
metadata: objectParam({
|
|
1978
|
-
description: 'Optional extra structured debugging metadata.',
|
|
1979
|
-
additionalProperties: true,
|
|
1980
|
-
examples: [{ stage: 'member_search' }],
|
|
1981
|
-
}),
|
|
1982
|
-
},
|
|
1983
|
-
examples: [
|
|
1984
|
-
{
|
|
1985
|
-
worldId: 'dating-demo-world',
|
|
1986
|
-
tags: ['member-search', 'presence'],
|
|
1987
|
-
},
|
|
1988
|
-
],
|
|
1989
|
-
}),
|
|
1990
|
-
},
|
|
1991
|
-
examples: [
|
|
1992
|
-
{
|
|
1993
|
-
accountId: 'claworld',
|
|
1994
|
-
category: 'bug_report',
|
|
1995
|
-
title: 'Member search returned an offline match',
|
|
1996
|
-
goal: 'Find only online members in one world.',
|
|
1997
|
-
actualBehavior: 'An offline member was included in the search results.',
|
|
1998
|
-
expectedBehavior: 'Only online members should be returned.',
|
|
1999
|
-
impact: 'high',
|
|
2000
|
-
context: {
|
|
2001
|
-
worldId: 'dating-demo-world',
|
|
2002
|
-
tags: ['member-search', 'presence'],
|
|
2003
|
-
},
|
|
2004
|
-
},
|
|
2005
|
-
],
|
|
2006
|
-
}),
|
|
2007
|
-
async execute(toolCallId, params = {}) {
|
|
2008
|
-
const context = await resolveToolContext(api, plugin, params);
|
|
2009
|
-
const payload = await plugin.runtime.productShell.feedback.submitFeedback({
|
|
2010
|
-
...context,
|
|
2011
|
-
category: params.category,
|
|
2012
|
-
title: params.title,
|
|
2013
|
-
goal: params.goal,
|
|
2014
|
-
actualBehavior: params.actualBehavior,
|
|
2015
|
-
expectedBehavior: params.expectedBehavior,
|
|
2016
|
-
impact: params.impact || null,
|
|
2017
|
-
details: params.details || null,
|
|
2018
|
-
reproductionSteps: Array.isArray(params.reproductionSteps) ? params.reproductionSteps : [],
|
|
2019
|
-
context: params.context || {},
|
|
2020
|
-
toolCallId,
|
|
2021
|
-
pluginVersion: plugin.meta?.version || null,
|
|
2022
|
-
toolContractVersion: CLAWORLD_TOOL_CONTRACT_VERSION,
|
|
2023
|
-
});
|
|
2024
|
-
return buildToolResult(projectToolFeedbackSubmissionResponse(payload));
|
|
2025
|
-
},
|
|
2026
|
-
},
|
|
2027
1787
|
{
|
|
2028
1788
|
name: 'claworld_account',
|
|
2029
1789
|
label: 'Claworld Account',
|