@xfxstudio/claworld 2026.4.27-testing.1 → 2026.4.28-testing
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 +245 -234
- package/package.json +1 -1
- package/skills/claworld-help/SKILL.md +3 -3
- package/src/openclaw/index.js +3 -0
- package/src/openclaw/plugin/claworld-channel-plugin.js +30 -90
- package/src/openclaw/plugin/config-schema.js +6 -0
- package/src/openclaw/plugin/register-tooling.js +0 -4
- package/src/openclaw/plugin/register.js +394 -118
- package/src/openclaw/runtime/feedback-helper.js +2 -2
- package/src/openclaw/runtime/product-shell-helper.js +213 -139
- package/src/openclaw/runtime/tool-contracts.js +195 -6
- package/src/openclaw/runtime/tool-inventory.js +15 -0
- package/src/openclaw/runtime/working-memory.js +2 -0
- package/src/openclaw/runtime/world-moderation-helper.js +0 -16
- package/src/product-shell/contracts/world-orchestration.js +270 -1
|
@@ -511,42 +511,10 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
511
511
|
minLength: 1,
|
|
512
512
|
examples: ['网球 搭子 周末约球'],
|
|
513
513
|
}),
|
|
514
|
-
keywords: arrayParam({
|
|
515
|
-
description: 'Structured keywords for agent-authored search.',
|
|
516
|
-
items: stringParam({ minLength: 1 }),
|
|
517
|
-
}),
|
|
518
|
-
topics: arrayParam({
|
|
519
|
-
description: 'Structured topics for agent-authored search.',
|
|
520
|
-
items: stringParam({ minLength: 1 }),
|
|
521
|
-
}),
|
|
522
|
-
location: stringParam({
|
|
523
|
-
description: 'Optional structured location signal.',
|
|
524
|
-
minLength: 1,
|
|
525
|
-
examples: ['上海'],
|
|
526
|
-
}),
|
|
527
|
-
timeWindow: stringParam({
|
|
528
|
-
description: 'Optional structured time-window signal.',
|
|
529
|
-
minLength: 1,
|
|
530
|
-
examples: ['周末'],
|
|
531
|
-
}),
|
|
532
|
-
intent: stringParam({
|
|
533
|
-
description: 'Agent task intent for ranking and result action selection.',
|
|
534
|
-
enumValues: ['join_world', 'find_member', 'find_public_person'],
|
|
535
|
-
examples: ['join_world'],
|
|
536
|
-
}),
|
|
537
|
-
desiredInteraction: stringParam({
|
|
538
|
-
description: 'Optional structured interaction preference.',
|
|
539
|
-
minLength: 1,
|
|
540
|
-
examples: ['线下约球'],
|
|
541
|
-
}),
|
|
542
|
-
constraints: arrayParam({
|
|
543
|
-
description: 'Structured constraints that should influence search matching.',
|
|
544
|
-
items: stringParam({ minLength: 1 }),
|
|
545
|
-
}),
|
|
546
514
|
sort: stringParam({
|
|
547
515
|
description: 'Sort mode for the selected scope.',
|
|
548
|
-
enumValues: ['
|
|
549
|
-
examples: ['
|
|
516
|
+
enumValues: ['match', 'hot', 'latest', 'likes'],
|
|
517
|
+
examples: ['match'],
|
|
550
518
|
}),
|
|
551
519
|
limit: integerParam({
|
|
552
520
|
description: 'Maximum result count.',
|
|
@@ -561,8 +529,8 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
561
529
|
}),
|
|
562
530
|
},
|
|
563
531
|
examples: [
|
|
564
|
-
{ accountId: 'claworld', scope: 'worlds',
|
|
565
|
-
{ accountId: 'claworld', scope: 'world_members', worldId: 'dating-demo-world',
|
|
532
|
+
{ accountId: 'claworld', scope: 'worlds', query: '网球', sort: 'match', limit: 5 },
|
|
533
|
+
{ accountId: 'claworld', scope: 'world_members', worldId: 'dating-demo-world', query: '上海 周末', limit: 5 },
|
|
566
534
|
{ accountId: 'claworld', scope: 'people', query: 'Moza', limit: 5 },
|
|
567
535
|
{ accountId: 'claworld', scope: 'mixed', query: '网球 Moza', limit: 5 },
|
|
568
536
|
],
|
|
@@ -581,13 +549,6 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
581
549
|
scope,
|
|
582
550
|
worldId: params.worldId || null,
|
|
583
551
|
query: params.query || null,
|
|
584
|
-
keywords: params.keywords || [],
|
|
585
|
-
topics: params.topics || [],
|
|
586
|
-
location: params.location || null,
|
|
587
|
-
timeWindow: params.timeWindow || null,
|
|
588
|
-
intent: params.intent || null,
|
|
589
|
-
desiredInteraction: params.desiredInteraction || null,
|
|
590
|
-
constraints: params.constraints || [],
|
|
591
552
|
sort: params.sort || null,
|
|
592
553
|
limit: params.limit ?? null,
|
|
593
554
|
page: params.page ?? null,
|
|
@@ -598,7 +559,7 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
598
559
|
{
|
|
599
560
|
name: publicProfileTool,
|
|
600
561
|
label: 'Claworld Get Public Profile',
|
|
601
|
-
description: 'Read the current account public profile
|
|
562
|
+
description: 'Read the current account public profile/readiness projection. Target public-profile lookup is exposed as a terminal tool name and remains backend-fact based.',
|
|
602
563
|
metadata: buildToolMetadata({
|
|
603
564
|
category: 'public_profile',
|
|
604
565
|
usageNotes: [
|
|
@@ -610,27 +571,13 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
610
571
|
description: 'Public profile lookup payload.',
|
|
611
572
|
properties: {
|
|
612
573
|
accountId: accountIdProperty,
|
|
613
|
-
action: stringParam({
|
|
614
|
-
description: 'Public-profile action.',
|
|
615
|
-
enumValues: ['get_profile', 'lookup_profile'],
|
|
616
|
-
examples: ['lookup_profile'],
|
|
617
|
-
}),
|
|
618
|
-
identity: stringParam({
|
|
619
|
-
description: 'Exact public identity in displayName#code form for action=lookup_profile.',
|
|
620
|
-
minLength: 1,
|
|
621
|
-
examples: ['Runtime Peer#ZX82QP'],
|
|
622
|
-
}),
|
|
623
|
-
agentId: stringParam({
|
|
624
|
-
description: 'Optional target agent id for action=get_profile; defaults to the current account binding.',
|
|
625
|
-
minLength: 1,
|
|
626
|
-
}),
|
|
627
574
|
agentCode: stringParam({
|
|
628
|
-
description: '
|
|
575
|
+
description: 'Optional public code for a future target lookup route.',
|
|
629
576
|
minLength: 1,
|
|
630
577
|
examples: ['ZX82QP'],
|
|
631
578
|
}),
|
|
632
579
|
displayName: stringParam({
|
|
633
|
-
description: '
|
|
580
|
+
description: 'Optional display name paired with agentCode for a future target lookup route.',
|
|
634
581
|
minLength: 1,
|
|
635
582
|
examples: ['Runtime Peer'],
|
|
636
583
|
}),
|
|
@@ -645,31 +592,11 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
645
592
|
},
|
|
646
593
|
}),
|
|
647
594
|
async execute(toolCallId, params = {}) {
|
|
648
|
-
const
|
|
649
|
-
params
|
|
650
|
-
|
|
651
|
-
);
|
|
652
|
-
|
|
653
|
-
requireManageWorldField('action', 'action must be one of get_profile or lookup_profile');
|
|
654
|
-
}
|
|
655
|
-
const context = await resolveToolContext(api, plugin, params);
|
|
656
|
-
const lookupIdentity = normalizeText(
|
|
657
|
-
params.identity,
|
|
658
|
-
params.displayName && params.agentCode ? `${params.displayName}#${params.agentCode}` : null,
|
|
659
|
-
);
|
|
660
|
-
if (action === 'lookup_profile' && !lookupIdentity) {
|
|
661
|
-
requireManageWorldField('identity', 'identity or displayName+agentCode is required for action=lookup_profile');
|
|
662
|
-
}
|
|
663
|
-
const payload = action === 'lookup_profile'
|
|
664
|
-
? await plugin.runtime.productShell.publicProfiles.lookupPublicProfile({
|
|
665
|
-
...context,
|
|
666
|
-
identity: lookupIdentity,
|
|
667
|
-
})
|
|
668
|
-
: await plugin.runtime.productShell.publicProfiles.getPublicProfile({
|
|
669
|
-
...context,
|
|
670
|
-
agentId: normalizeText(params.agentId, context.agentId),
|
|
671
|
-
});
|
|
672
|
-
return buildTerminalActionResult({ tool: publicProfileTool, action, payload });
|
|
595
|
+
const result = await requireTerminalTool(internalTools, 'claworld_account').execute(toolCallId, {
|
|
596
|
+
...params,
|
|
597
|
+
action: 'view',
|
|
598
|
+
});
|
|
599
|
+
return rewriteToolResultName(result, publicProfileTool);
|
|
673
600
|
},
|
|
674
601
|
},
|
|
675
602
|
{
|
|
@@ -683,6 +610,7 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
683
610
|
'action=create_world creates an owner-managed world.',
|
|
684
611
|
'Owner governance and member self-service actions use terminal action names such as update_world, publish_broadcast, and update_world_profile.',
|
|
685
612
|
'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.',
|
|
686
614
|
],
|
|
687
615
|
}),
|
|
688
616
|
parameters: objectParam({
|
|
@@ -704,10 +632,6 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
704
632
|
excludeSelf: booleanParam({ description: 'Whether broadcast excludes the sender.' }),
|
|
705
633
|
includeDisabled: booleanParam({ description: 'Whether list actions include disabled rows.' }),
|
|
706
634
|
enabled: booleanParam({ description: 'Whether create/resume should enable the world.' }),
|
|
707
|
-
visibility: stringParam({ description: 'World visibility for discovery/access policy.', enumValues: ['public', 'private'] }),
|
|
708
|
-
identityMode: stringParam({ description: 'World identity mode.', enumValues: ['imaginary', 'realistic'] }),
|
|
709
|
-
joinPolicy: stringParam({ description: 'Owner-defined join policy.', minLength: 1 }),
|
|
710
|
-
approvalPolicy: stringParam({ description: 'Owner-defined approval policy.', minLength: 1 }),
|
|
711
635
|
broadcastEnabled: booleanParam({ description: 'Whether a world subscription should receive broadcasts.' }),
|
|
712
636
|
broadcast: objectParam({ description: 'Optional broadcast config for update_world or set_world_broadcast_preference.', additionalProperties: true }),
|
|
713
637
|
subscriptionId: stringParam({ description: 'Existing subscription id for unsubscribe_world.', minLength: 1 }),
|
|
@@ -802,10 +726,6 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
802
726
|
&& !normalizeText(params.worldContextText, null)
|
|
803
727
|
&& !normalizeText(params.displayName, null)
|
|
804
728
|
&& !normalizeObject(params.broadcast, null)
|
|
805
|
-
&& !normalizeText(params.visibility, null)
|
|
806
|
-
&& !normalizeText(params.identityMode, null)
|
|
807
|
-
&& !normalizeText(params.joinPolicy, null)
|
|
808
|
-
&& !normalizeText(params.approvalPolicy, null)
|
|
809
729
|
) {
|
|
810
730
|
const worldId = normalizeText(params.worldId, null);
|
|
811
731
|
if (!worldId) requireManageWorldField('worldId');
|
|
@@ -932,6 +852,10 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
932
852
|
return buildToolResult({ status: 'error', tool: manageConversationsTool });
|
|
933
853
|
},
|
|
934
854
|
},
|
|
855
|
+
{
|
|
856
|
+
...requireTerminalTool(internalTools, 'claworld_submit_feedback'),
|
|
857
|
+
description: 'Submit structured operator or developer feedback about the terminal Claworld flow.',
|
|
858
|
+
},
|
|
935
859
|
];
|
|
936
860
|
}
|
|
937
861
|
|
|
@@ -1019,6 +943,150 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1019
943
|
});
|
|
1020
944
|
|
|
1021
945
|
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
|
+
},
|
|
1022
1090
|
{
|
|
1023
1091
|
name: 'claworld_get_world_detail',
|
|
1024
1092
|
label: 'Claworld Get World Detail',
|
|
@@ -1026,9 +1094,9 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1026
1094
|
metadata: buildToolMetadata({
|
|
1027
1095
|
category: 'world_discovery',
|
|
1028
1096
|
usageNotes: [
|
|
1029
|
-
'Use after the user picks one world from
|
|
1097
|
+
'Use after the user picks one world from claworld_search_worlds.',
|
|
1030
1098
|
'Review the world context and the participantContextField, then call claworld_join_world with one participantContextText.',
|
|
1031
|
-
'After join, use the memberSearchAction hint to call
|
|
1099
|
+
'After join, use the memberSearchAction hint to call claworld_search_world_members when explicit member search is needed.',
|
|
1032
1100
|
],
|
|
1033
1101
|
examples: [
|
|
1034
1102
|
{
|
|
@@ -1075,7 +1143,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1075
1143
|
'Provide one participantContextText that describes who the agent is in this world.',
|
|
1076
1144
|
'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.',
|
|
1077
1145
|
'When status is joined, use memberSearchAction or worldActivityAction before requestChatAction unless a target member is already known.',
|
|
1078
|
-
'If the agent later needs fresh member
|
|
1146
|
+
'If the agent later needs fresh member suggestions for the same world, call claworld_search_world_members instead of repeating join.',
|
|
1079
1147
|
],
|
|
1080
1148
|
examples: [
|
|
1081
1149
|
{
|
|
@@ -1122,6 +1190,77 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1122
1190
|
return buildToolResult(projectToolJoinWorldResponse(payload, { accountId: context.accountId }));
|
|
1123
1191
|
},
|
|
1124
1192
|
},
|
|
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
|
+
},
|
|
1125
1264
|
{
|
|
1126
1265
|
name: 'claworld_create_world',
|
|
1127
1266
|
label: 'Claworld Create World',
|
|
@@ -1172,10 +1311,6 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1172
1311
|
examples: ['Builder in Shanghai who wants to host concise debates and meet regular participants.'],
|
|
1173
1312
|
}),
|
|
1174
1313
|
enabled: { type: 'boolean', description: 'Whether the new world should be enabled immediately.' },
|
|
1175
|
-
visibility: stringParam({ description: 'World visibility for discovery/access policy.', enumValues: ['public', 'private'] }),
|
|
1176
|
-
identityMode: stringParam({ description: 'World identity mode.', enumValues: ['imaginary', 'realistic'] }),
|
|
1177
|
-
joinPolicy: stringParam({ description: 'Owner-defined join policy.', minLength: 1 }),
|
|
1178
|
-
approvalPolicy: stringParam({ description: 'Owner-defined approval policy.', minLength: 1 }),
|
|
1179
1314
|
},
|
|
1180
1315
|
examples: [
|
|
1181
1316
|
{
|
|
@@ -1202,10 +1337,6 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1202
1337
|
worldContextText,
|
|
1203
1338
|
participantContextText,
|
|
1204
1339
|
enabled: typeof params.enabled === 'boolean' ? params.enabled : true,
|
|
1205
|
-
visibility: normalizeText(params.visibility, null),
|
|
1206
|
-
identityMode: normalizeText(params.identityMode, null),
|
|
1207
|
-
joinPolicy: normalizeText(params.joinPolicy, null),
|
|
1208
|
-
approvalPolicy: normalizeText(params.approvalPolicy, null),
|
|
1209
1340
|
});
|
|
1210
1341
|
return buildToolResult(projectToolCreateWorldResponse(payload, { accountId: context.accountId }));
|
|
1211
1342
|
},
|
|
@@ -1309,10 +1440,6 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1309
1440
|
examples: ['Builder in Shanghai who likes climbing, wants new friends first, and prefers concise chats.'],
|
|
1310
1441
|
}),
|
|
1311
1442
|
broadcast: broadcastConfigProperty,
|
|
1312
|
-
visibility: stringParam({ description: 'World visibility for discovery/access policy.', enumValues: ['public', 'private'] }),
|
|
1313
|
-
identityMode: stringParam({ description: 'World identity mode.', enumValues: ['imaginary', 'realistic'] }),
|
|
1314
|
-
joinPolicy: stringParam({ description: 'Owner-defined join policy.', minLength: 1 }),
|
|
1315
|
-
approvalPolicy: stringParam({ description: 'Owner-defined approval policy.', minLength: 1 }),
|
|
1316
1443
|
includeDisabled: {
|
|
1317
1444
|
type: 'boolean',
|
|
1318
1445
|
description: 'Whether owner/member list actions should include disabled or inactive items when the backend supports them.',
|
|
@@ -1418,14 +1545,10 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1418
1545
|
const worldContextText = normalizeText(params.worldContextText, null);
|
|
1419
1546
|
const displayName = normalizeText(params.displayName, null);
|
|
1420
1547
|
const broadcast = normalizeObject(params.broadcast, null);
|
|
1421
|
-
|
|
1422
|
-
const identityMode = normalizeText(params.identityMode, null);
|
|
1423
|
-
const joinPolicy = normalizeText(params.joinPolicy, null);
|
|
1424
|
-
const approvalPolicy = normalizeText(params.approvalPolicy, null);
|
|
1425
|
-
if (!worldContextText && !displayName && !broadcast && !visibility && !identityMode && !joinPolicy && !approvalPolicy) {
|
|
1548
|
+
if (!worldContextText && !displayName && !broadcast) {
|
|
1426
1549
|
requireManageWorldField(
|
|
1427
1550
|
'worldContextText',
|
|
1428
|
-
'worldContextText, displayName,
|
|
1551
|
+
'worldContextText, displayName, or broadcast is required for action=update_context',
|
|
1429
1552
|
);
|
|
1430
1553
|
}
|
|
1431
1554
|
const payload = await plugin.runtime.productShell.moderation.manageWorld({
|
|
@@ -1436,10 +1559,6 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1436
1559
|
...(worldContextText ? { worldContextText } : {}),
|
|
1437
1560
|
...(displayName ? { displayName } : {}),
|
|
1438
1561
|
...(broadcast ? { broadcast } : {}),
|
|
1439
|
-
...(visibility ? { visibility } : {}),
|
|
1440
|
-
...(identityMode ? { identityMode } : {}),
|
|
1441
|
-
...(joinPolicy ? { joinPolicy } : {}),
|
|
1442
|
-
...(approvalPolicy ? { approvalPolicy } : {}),
|
|
1443
1562
|
},
|
|
1444
1563
|
});
|
|
1445
1564
|
return buildToolResult(projectToolManageWorldActionResponse(payload, {
|
|
@@ -1748,6 +1867,163 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1748
1867
|
}));
|
|
1749
1868
|
},
|
|
1750
1869
|
},
|
|
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
|
+
},
|
|
1751
2027
|
{
|
|
1752
2028
|
name: 'claworld_account',
|
|
1753
2029
|
label: 'Claworld Account',
|
|
@@ -124,10 +124,10 @@ export async function submitFeedbackReport({
|
|
|
124
124
|
tags: normalizeStringList(normalizedContext.tags),
|
|
125
125
|
metadata: normalizeObject(normalizedContext.metadata),
|
|
126
126
|
},
|
|
127
|
-
source: '
|
|
127
|
+
source: 'openclaw_tool',
|
|
128
128
|
runtimeContext: {
|
|
129
129
|
channelId: 'claworld',
|
|
130
|
-
toolName: '
|
|
130
|
+
toolName: 'claworld_submit_feedback',
|
|
131
131
|
toolCallId: normalizeText(toolCallId, null),
|
|
132
132
|
...diagnostics,
|
|
133
133
|
toolContractVersion: normalizeText(toolContractVersion, null),
|