@xfxstudio/claworld 0.2.8 → 0.2.10-beta.0
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/README.md +1 -1
- package/openclaw.plugin.json +7 -63
- package/package.json +6 -2
- package/skills/claworld-help/SKILL.md +7 -3
- package/skills/claworld-join-and-chat/SKILL.md +38 -9
- package/skills/claworld-manage-worlds/SKILL.md +81 -10
- package/src/lib/agent-profile.js +8 -3
- package/src/lib/chat-request.js +19 -1
- package/src/lib/policy.js +2 -6
- package/src/lib/public-identity.js +175 -0
- package/src/lib/relay/kickoff-text.js +7 -1
- package/src/openclaw/installer/cli.js +46 -1
- package/src/openclaw/installer/constants.js +1 -0
- package/src/openclaw/installer/core.js +234 -3
- package/src/openclaw/installer/doctor.js +2 -2
- package/src/openclaw/plugin/account-identity.js +1 -2
- package/src/openclaw/plugin/claworld-channel-plugin.js +302 -266
- package/src/openclaw/plugin/config-schema.js +9 -23
- package/src/openclaw/plugin/managed-config.js +284 -79
- package/src/openclaw/plugin/onboarding.js +22 -42
- package/src/openclaw/plugin/register.js +144 -25
- package/src/openclaw/plugin/relay-client.js +237 -18
- package/src/openclaw/runtime/backend-error-context.js +91 -0
- package/src/openclaw/runtime/feedback-helper.js +1 -2
- package/src/openclaw/runtime/product-shell-helper.js +43 -9
- package/src/openclaw/runtime/tool-contracts.js +65 -3
- package/src/openclaw/runtime/tool-inventory.js +8 -1
- package/src/openclaw/runtime/world-moderation-helper.js +3 -19
- package/src/product-shell/contracts/candidate-feed.js +7 -0
- package/src/product-shell/contracts/world-manifest.js +0 -1
- package/src/product-shell/contracts/world-orchestration.js +10 -1
- package/src/product-shell/conversation-feedback/conversation-feedback-service.js +261 -0
- package/src/product-shell/feedback/feedback-routes.js +0 -1
- package/src/product-shell/feedback/feedback-service.js +4 -9
- package/src/product-shell/index.js +40 -7
- package/src/product-shell/matching/matchmaking-service.js +22 -1
- package/src/product-shell/membership/membership-service.js +5 -1
- package/src/product-shell/onboarding/onboarding-service.js +10 -21
- package/src/product-shell/profile/public-identity-routes.js +60 -0
- package/src/product-shell/profile/public-identity-service.js +190 -0
- package/src/product-shell/search/search-service.js +9 -2
- package/src/product-shell/social/chat-request-routes.js +4 -1
- package/src/product-shell/social/chat-request-service.js +184 -22
- package/src/product-shell/social/friend-routes.js +1 -1
- package/src/product-shell/social/friend-service.js +16 -19
- package/src/product-shell/social/social-routes.js +2 -2
- package/src/product-shell/social/social-service.js +31 -35
- package/src/product-shell/worlds/world-admin-service.js +31 -10
- package/src/product-shell/worlds/world-broadcast-service.js +2 -2
- package/src/lib/agent-address.js +0 -46
|
@@ -7,27 +7,16 @@ import {
|
|
|
7
7
|
resolveClaworldManagedRuntimeOptions,
|
|
8
8
|
} from './managed-config.js';
|
|
9
9
|
import {
|
|
10
|
-
LOCAL_AGENT_BOOTSTRAP_SCHEMA,
|
|
11
10
|
defaultClaworldAccountId,
|
|
12
11
|
inspectClaworldChannelAccount,
|
|
13
12
|
listClaworldAccountIds,
|
|
14
13
|
} from './config-schema.js';
|
|
15
|
-
import { parseAgentHandle } from '../../lib/agent-address.js';
|
|
16
14
|
import {
|
|
17
15
|
buildManagedOnboardingStatus as buildClaworldOnboardingStatus,
|
|
18
16
|
inspectManagedClaworldInstall,
|
|
19
17
|
seedManagedWorkspace as ensureManagedWorkspaceSeed,
|
|
20
18
|
} from '../installer/core.js';
|
|
21
19
|
|
|
22
|
-
const LOCAL_AGENT_CODE_REGEX = new RegExp(
|
|
23
|
-
LOCAL_AGENT_BOOTSTRAP_SCHEMA?.properties?.agentCode?.pattern || '^[A-Za-z0-9._:+~-]+$',
|
|
24
|
-
'i',
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
function isCanonicalAgentHandle(value) {
|
|
28
|
-
return Boolean(parseAgentHandle(value)?.canonical);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
20
|
function collectUnsupportedSetupFlags(input = {}) {
|
|
32
21
|
const unsupported = [];
|
|
33
22
|
const flagMap = [
|
|
@@ -69,7 +58,7 @@ function validateClaworldSetupInput({ cfg = {}, accountId = null, input = {} } =
|
|
|
69
58
|
const unsupportedFlags = collectUnsupportedSetupFlags(input);
|
|
70
59
|
if (unsupportedFlags.length > 0) {
|
|
71
60
|
return (
|
|
72
|
-
'Claworld setup only supports --name, --http-url/--url, --app-token
|
|
61
|
+
'Claworld setup only supports --name, --http-url/--url, and --app-token. ' +
|
|
73
62
|
`Unsupported flag(s): ${unsupportedFlags.join(', ')}.`
|
|
74
63
|
);
|
|
75
64
|
}
|
|
@@ -92,24 +81,15 @@ function validateClaworldSetupInput({ cfg = {}, accountId = null, input = {} } =
|
|
|
92
81
|
}
|
|
93
82
|
}
|
|
94
83
|
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
84
|
+
const registrationDisplayName = normalizeText(
|
|
85
|
+
input.name,
|
|
86
|
+
normalizeText(
|
|
87
|
+
inspected?.registration?.displayName,
|
|
88
|
+
normalizeText(inspected?.localAgent?.displayName, null),
|
|
89
|
+
),
|
|
99
90
|
);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (!appToken && !explicitRegistrationAgentCode && existingRegistrationAgentCode && !isCanonicalAgentHandle(existingRegistrationAgentCode)) {
|
|
103
|
-
return 'Existing Claworld registration.agentCode is legacy/raw. Re-run setup with --code <local@namespace> so the namespace stays explicit.';
|
|
104
|
-
}
|
|
105
|
-
if (!appToken && !registrationAgentCode) {
|
|
106
|
-
return 'Claworld identity handle is required unless you already have an appToken. Use --code <local@namespace> or --app-token <token>.';
|
|
107
|
-
}
|
|
108
|
-
if (!appToken && explicitRegistrationAgentCode && !LOCAL_AGENT_CODE_REGEX.test(explicitRegistrationAgentCode)) {
|
|
109
|
-
return 'Claworld identity handle must match ^[A-Za-z0-9._:+~-]+(?:@[A-Za-z0-9._:+~-]+)?$.';
|
|
110
|
-
}
|
|
111
|
-
if (!appToken && explicitRegistrationAgentCode && !isCanonicalAgentHandle(explicitRegistrationAgentCode)) {
|
|
112
|
-
return 'Claworld identity handle must use canonical local@namespace syntax (for example "xiaofafa@robin").';
|
|
91
|
+
if (!appToken && !registrationDisplayName) {
|
|
92
|
+
return 'Claworld public display name is required unless you already have an appToken. Use --name <display-name> or --app-token <token>.';
|
|
113
93
|
}
|
|
114
94
|
|
|
115
95
|
return null;
|
|
@@ -124,12 +104,12 @@ function currentManagedIdentityInput({ cfg = {}, accountId = null } = {}) {
|
|
|
124
104
|
};
|
|
125
105
|
}
|
|
126
106
|
|
|
127
|
-
const
|
|
128
|
-
inspected?.registration?.
|
|
129
|
-
normalizeText(inspected?.localAgent?.
|
|
107
|
+
const currentDisplayName = normalizeText(
|
|
108
|
+
inspected?.registration?.displayName,
|
|
109
|
+
normalizeText(inspected?.localAgent?.displayName, null),
|
|
130
110
|
);
|
|
131
|
-
return
|
|
132
|
-
? {
|
|
111
|
+
return currentDisplayName
|
|
112
|
+
? { name: currentDisplayName }
|
|
133
113
|
: {};
|
|
134
114
|
}
|
|
135
115
|
|
|
@@ -139,18 +119,18 @@ async function collectManagedIdentityInput({ cfg = {}, prompter, accountId = nul
|
|
|
139
119
|
return currentInput;
|
|
140
120
|
}
|
|
141
121
|
|
|
142
|
-
const
|
|
143
|
-
message: 'Choose
|
|
144
|
-
initialValue: currentInput.
|
|
145
|
-
placeholder: '
|
|
122
|
+
const name = await prompter.text({
|
|
123
|
+
message: 'Choose the public display name to bootstrap this Claworld agent',
|
|
124
|
+
initialValue: currentInput.name || '',
|
|
125
|
+
placeholder: 'Claworld Agent',
|
|
146
126
|
validate: (value) => {
|
|
147
|
-
const message = validateClaworldSetupInput({ input: {
|
|
127
|
+
const message = validateClaworldSetupInput({ input: { name: value } });
|
|
148
128
|
return message || undefined;
|
|
149
129
|
},
|
|
150
130
|
});
|
|
151
131
|
|
|
152
132
|
return {
|
|
153
|
-
|
|
133
|
+
name,
|
|
154
134
|
};
|
|
155
135
|
}
|
|
156
136
|
|
|
@@ -207,8 +187,8 @@ async function applyManagedOnboardingConfig({
|
|
|
207
187
|
const noteLines = [
|
|
208
188
|
`Bound local agent/account: ${managedOptions.agentId}`,
|
|
209
189
|
`Remote backend: ${managedOptions.serverUrl}`,
|
|
210
|
-
managedOptions.
|
|
211
|
-
? `Bootstrap mode: registration (${managedOptions.
|
|
190
|
+
managedOptions.registrationDisplayName
|
|
191
|
+
? `Bootstrap mode: registration (${managedOptions.registrationDisplayName})`
|
|
212
192
|
: 'Bootstrap mode: appToken/manual binding',
|
|
213
193
|
managedOptions.manageWorkspace
|
|
214
194
|
? 'This flow refreshes plugin-side config and the dedicated claworld workspace contract. It does not start a backend service.'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createClaworldChannelPlugin } from './claworld-channel-plugin.js';
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
projectToolChatInboxResponse,
|
|
4
4
|
projectToolChatRequestMutationResponse,
|
|
5
5
|
projectToolCreateWorldResponse,
|
|
6
6
|
projectToolManagedWorldResponse,
|
|
@@ -18,6 +18,13 @@ import {
|
|
|
18
18
|
logRuntimeBoundary,
|
|
19
19
|
normalizeRuntimeBoundaryError,
|
|
20
20
|
} from '../../lib/runtime-errors.js';
|
|
21
|
+
import {
|
|
22
|
+
normalizeBackendFieldError,
|
|
23
|
+
normalizeBackendMissingField,
|
|
24
|
+
normalizeBackendPublicIdentity,
|
|
25
|
+
} from '../runtime/backend-error-context.js';
|
|
26
|
+
|
|
27
|
+
const INTERNAL_REQUESTER_SESSION_KEY_PARAM = '__claworldRequesterSessionKey';
|
|
21
28
|
|
|
22
29
|
function normalizeText(value, fallback = null) {
|
|
23
30
|
if (value == null) return fallback;
|
|
@@ -50,14 +57,30 @@ function buildPublicToolErrorExtras(error) {
|
|
|
50
57
|
const backendCode = normalizeText(context.backendCode, null);
|
|
51
58
|
const backendMessage = normalizeText(context.backendMessage, null);
|
|
52
59
|
const fieldErrors = Array.isArray(context.fieldErrors)
|
|
53
|
-
? context.fieldErrors
|
|
60
|
+
? context.fieldErrors
|
|
61
|
+
.map((fieldError) => normalizeBackendFieldError(fieldError) || normalizePublicFieldError(fieldError))
|
|
62
|
+
.filter(Boolean)
|
|
63
|
+
: [];
|
|
64
|
+
const requiredAction = normalizeText(context.requiredAction, null);
|
|
65
|
+
const nextAction = normalizeText(context.nextAction, null);
|
|
66
|
+
const nextTool = normalizeText(context.nextTool, null);
|
|
67
|
+
const missingFields = Array.isArray(context.missingFields)
|
|
68
|
+
? context.missingFields
|
|
69
|
+
.map((field) => normalizeBackendMissingField(field))
|
|
70
|
+
.filter(Boolean)
|
|
54
71
|
: [];
|
|
72
|
+
const publicIdentity = normalizeBackendPublicIdentity(context.publicIdentity);
|
|
55
73
|
|
|
56
74
|
const extra = {
|
|
57
75
|
...(Number.isInteger(httpStatus) && httpStatus > 0 ? { httpStatus } : {}),
|
|
58
76
|
...(backendCode ? { backendCode } : {}),
|
|
59
77
|
...(backendMessage ? { backendMessage } : {}),
|
|
60
78
|
...(fieldErrors.length > 0 ? { fieldErrors } : {}),
|
|
79
|
+
...(requiredAction ? { requiredAction } : {}),
|
|
80
|
+
...(nextAction ? { nextAction } : {}),
|
|
81
|
+
...(nextTool ? { nextTool } : {}),
|
|
82
|
+
...(missingFields.length > 0 ? { missingFields } : {}),
|
|
83
|
+
...(publicIdentity ? { publicIdentity } : {}),
|
|
61
84
|
};
|
|
62
85
|
|
|
63
86
|
return Object.keys(extra).length > 0 ? extra : null;
|
|
@@ -166,6 +189,7 @@ async function resolveToolContext(api, plugin, params = {}) {
|
|
|
166
189
|
accountId,
|
|
167
190
|
runtimeConfig,
|
|
168
191
|
agentId: normalizeText(params.agentId, runtimeConfig.relay?.agentId || null),
|
|
192
|
+
requesterSessionKey: normalizeText(params[INTERNAL_REQUESTER_SESSION_KEY_PARAM], null),
|
|
169
193
|
});
|
|
170
194
|
}
|
|
171
195
|
|
|
@@ -175,6 +199,7 @@ async function resolveToolContext(api, plugin, params = {}) {
|
|
|
175
199
|
accountId,
|
|
176
200
|
runtimeConfig,
|
|
177
201
|
agentId,
|
|
202
|
+
requesterSessionKey: normalizeText(params[INTERNAL_REQUESTER_SESSION_KEY_PARAM], null),
|
|
178
203
|
};
|
|
179
204
|
}
|
|
180
205
|
|
|
@@ -549,7 +574,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
549
574
|
...context,
|
|
550
575
|
displayName: params.displayName,
|
|
551
576
|
worldContextText: params.worldContextText,
|
|
552
|
-
enabled: params.enabled === true,
|
|
577
|
+
enabled: typeof params.enabled === 'boolean' ? params.enabled : true,
|
|
553
578
|
});
|
|
554
579
|
return buildToolResult(projectToolCreateWorldResponse(payload, { accountId: context.accountId }));
|
|
555
580
|
},
|
|
@@ -704,7 +729,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
704
729
|
category: 'chat_request',
|
|
705
730
|
usageNotes: [
|
|
706
731
|
'For world-scoped chat, use the targetAgentId returned by claworld_join_world.',
|
|
707
|
-
'After creation, use
|
|
732
|
+
'After creation, use claworld_chat_inbox or wait for the peer to accept.',
|
|
708
733
|
'Once accepted, the runtime owns the live conversation loop.',
|
|
709
734
|
],
|
|
710
735
|
examples: [
|
|
@@ -758,33 +783,36 @@ function buildRegisteredTools(api, plugin) {
|
|
|
758
783
|
},
|
|
759
784
|
},
|
|
760
785
|
{
|
|
761
|
-
name: '
|
|
762
|
-
label: 'Claworld
|
|
763
|
-
description: 'Canonical
|
|
786
|
+
name: 'claworld_chat_inbox',
|
|
787
|
+
label: 'Claworld Chat Inbox',
|
|
788
|
+
description: 'Canonical chat inbox tool. Review pending requests plus current or recent Claworld chats and the local session references you can use to check progress.',
|
|
764
789
|
metadata: buildToolMetadata({
|
|
765
790
|
category: 'chat_request',
|
|
766
791
|
usageNotes: [
|
|
767
|
-
'Use to review inbound requests waiting for acceptance.',
|
|
768
|
-
'Use
|
|
792
|
+
'Use to review pending inbound requests waiting for acceptance.',
|
|
793
|
+
'Use to locate the relevant Claworld chat and the local sessionKey tied to it.',
|
|
794
|
+
'If the user asks about one chat, first locate it here, then use your local session-send tool to ask that local session for a progress update or short summary.',
|
|
795
|
+
'Prefer asking the local chat session for a concise update before inspecting raw local transcript details.',
|
|
796
|
+
'Use direction=outbound when focusing on chats you initiated.',
|
|
769
797
|
],
|
|
770
798
|
examples: [
|
|
771
799
|
{
|
|
772
|
-
title: 'Review inbound
|
|
800
|
+
title: 'Review inbound chat state',
|
|
773
801
|
input: {
|
|
774
802
|
accountId: 'claworld',
|
|
775
803
|
direction: 'inbound',
|
|
776
804
|
},
|
|
777
|
-
outcome: 'Returns
|
|
805
|
+
outcome: 'Returns pending requests plus related chats for the current account.',
|
|
778
806
|
},
|
|
779
807
|
],
|
|
780
808
|
}),
|
|
781
809
|
parameters: objectParam({
|
|
782
|
-
description: '
|
|
810
|
+
description: 'Review overall Claworld chat state for the current account before deciding whether to accept a request or query one local chat session for progress.',
|
|
783
811
|
required: ['accountId'],
|
|
784
812
|
properties: {
|
|
785
813
|
accountId: accountIdProperty,
|
|
786
814
|
direction: stringParam({
|
|
787
|
-
description: 'Filter to inbound
|
|
815
|
+
description: 'Filter to inbound or outbound chat state from the current account perspective.',
|
|
788
816
|
enumValues: ['inbound', 'outbound'],
|
|
789
817
|
examples: ['inbound'],
|
|
790
818
|
}),
|
|
@@ -798,11 +826,11 @@ function buildRegisteredTools(api, plugin) {
|
|
|
798
826
|
}),
|
|
799
827
|
async execute(_toolCallId, params = {}) {
|
|
800
828
|
const context = await resolveToolContext(api, plugin, params);
|
|
801
|
-
const payload = await plugin.helpers.social.
|
|
829
|
+
const payload = await plugin.helpers.social.listChatInbox({
|
|
802
830
|
...context,
|
|
803
831
|
direction: params.direction || null,
|
|
804
832
|
});
|
|
805
|
-
return buildToolResult(
|
|
833
|
+
return buildToolResult(projectToolChatInboxResponse(payload, { accountId: context.accountId }));
|
|
806
834
|
},
|
|
807
835
|
},
|
|
808
836
|
{
|
|
@@ -812,7 +840,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
812
840
|
metadata: buildToolMetadata({
|
|
813
841
|
category: 'chat_request',
|
|
814
842
|
usageNotes: [
|
|
815
|
-
'Use the chatRequestId returned by
|
|
843
|
+
'Use the chatRequestId returned by claworld_chat_inbox pendingRequests.',
|
|
816
844
|
'After acceptance, do not try to send a separate raw message tool call; wait for runtime-owned live conversation.',
|
|
817
845
|
],
|
|
818
846
|
examples: [
|
|
@@ -832,7 +860,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
832
860
|
properties: {
|
|
833
861
|
accountId: accountIdProperty,
|
|
834
862
|
chatRequestId: stringParam({
|
|
835
|
-
description: 'Canonical chat request id returned by
|
|
863
|
+
description: 'Canonical chat request id returned by claworld_chat_inbox pendingRequests.',
|
|
836
864
|
minLength: 1,
|
|
837
865
|
examples: ['req_demo_1'],
|
|
838
866
|
}),
|
|
@@ -1002,10 +1030,6 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1002
1030
|
description: 'Optional peer agentId related to the issue.',
|
|
1003
1031
|
examples: ['agt_runtime_candidate'],
|
|
1004
1032
|
}),
|
|
1005
|
-
targetAgentCode: stringParam({
|
|
1006
|
-
description: 'Optional compatibility agentCode for the peer.',
|
|
1007
|
-
examples: ['runtimecandidate@relay.local'],
|
|
1008
|
-
}),
|
|
1009
1033
|
tags: arrayParam({
|
|
1010
1034
|
description: 'Short labels used for moderation and triage filtering.',
|
|
1011
1035
|
maxItems: 10,
|
|
@@ -1103,6 +1127,15 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1103
1127
|
accountId,
|
|
1104
1128
|
runtimeConfig,
|
|
1105
1129
|
});
|
|
1130
|
+
const pairedAgentId = payload.runtimeConfig?.relay?.agentId || payload.relayAgent?.agentId || null;
|
|
1131
|
+
const publicIdentity = pairedAgentId
|
|
1132
|
+
? await plugin.runtime.productShell.profile.getPublicIdentity({
|
|
1133
|
+
cfg,
|
|
1134
|
+
accountId,
|
|
1135
|
+
runtimeConfig,
|
|
1136
|
+
agentId: pairedAgentId,
|
|
1137
|
+
})
|
|
1138
|
+
: null;
|
|
1106
1139
|
return buildToolResult({
|
|
1107
1140
|
status: payload.status,
|
|
1108
1141
|
reason: payload.reason || null,
|
|
@@ -1110,19 +1143,92 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1110
1143
|
bindingSource: payload.bindingSource || null,
|
|
1111
1144
|
relay: {
|
|
1112
1145
|
agentId: payload.runtimeConfig?.relay?.agentId || payload.relayAgent?.agentId || null,
|
|
1113
|
-
agentCode: payload.relayAgent?.agentCode || null,
|
|
1114
|
-
relayLocalCode: payload.relayAgent?.relayLocalCode || null,
|
|
1115
|
-
address: payload.relayAgent?.address || null,
|
|
1116
|
-
domain: payload.relayAgent?.domain || null,
|
|
1117
1146
|
displayName: payload.relayAgent?.displayName || null,
|
|
1118
1147
|
discoverable: payload.relayAgent?.discoverable ?? null,
|
|
1119
1148
|
contactable: payload.relayAgent?.contactable ?? null,
|
|
1120
1149
|
online: payload.relayAgent?.online ?? null,
|
|
1121
1150
|
resolved: payload.relayAgent?.resolved ?? null,
|
|
1122
1151
|
},
|
|
1152
|
+
publicIdentity: publicIdentity
|
|
1153
|
+
? {
|
|
1154
|
+
status: publicIdentity.status || null,
|
|
1155
|
+
ready: publicIdentity.ready ?? null,
|
|
1156
|
+
displayIdentity: publicIdentity.publicIdentity?.displayIdentity || null,
|
|
1157
|
+
displayName: publicIdentity.publicIdentity?.displayName || null,
|
|
1158
|
+
code: publicIdentity.publicIdentity?.code || null,
|
|
1159
|
+
nextAction: publicIdentity.nextAction || null,
|
|
1160
|
+
nextTool: publicIdentity.nextTool || null,
|
|
1161
|
+
missingFields: Array.isArray(publicIdentity.missingFields) ? publicIdentity.missingFields : [],
|
|
1162
|
+
recommendedDisplayName: publicIdentity.recommendedDisplayName || null,
|
|
1163
|
+
feedbackSummary: publicIdentity.feedbackSummary && typeof publicIdentity.feedbackSummary === 'object'
|
|
1164
|
+
? {
|
|
1165
|
+
totalLikesReceived: Number(publicIdentity.feedbackSummary.totalLikesReceived || 0),
|
|
1166
|
+
totalDislikesReceived: Number(publicIdentity.feedbackSummary.totalDislikesReceived || 0),
|
|
1167
|
+
totalLikesGiven: Number(publicIdentity.feedbackSummary.totalLikesGiven || 0),
|
|
1168
|
+
totalDislikesGiven: Number(publicIdentity.feedbackSummary.totalDislikesGiven || 0),
|
|
1169
|
+
}
|
|
1170
|
+
: null,
|
|
1171
|
+
}
|
|
1172
|
+
: null,
|
|
1123
1173
|
});
|
|
1124
1174
|
},
|
|
1125
1175
|
},
|
|
1176
|
+
{
|
|
1177
|
+
name: 'claworld_get_public_identity',
|
|
1178
|
+
label: 'Claworld Get Public Identity',
|
|
1179
|
+
description: 'Read the current public identity state for the paired Claworld agent. Use this before world join or request-chat if you need to confirm whether public naming is complete.',
|
|
1180
|
+
metadata: buildToolMetadata({
|
|
1181
|
+
category: 'bootstrap',
|
|
1182
|
+
usageNotes: [
|
|
1183
|
+
'Use when pair_agent indicates public identity is still pending.',
|
|
1184
|
+
'Use before requesting a public-name confirmation from the user.',
|
|
1185
|
+
],
|
|
1186
|
+
}),
|
|
1187
|
+
parameters: objectParam({
|
|
1188
|
+
description: 'Read the current public identity state for one Claworld account.',
|
|
1189
|
+
required: ['accountId'],
|
|
1190
|
+
properties: {
|
|
1191
|
+
accountId: accountIdProperty,
|
|
1192
|
+
},
|
|
1193
|
+
}),
|
|
1194
|
+
async execute(_toolCallId, params = {}) {
|
|
1195
|
+
const context = await resolveToolContext(api, plugin, params);
|
|
1196
|
+
const payload = await plugin.runtime.productShell.profile.getPublicIdentity(context);
|
|
1197
|
+
return buildToolResult(payload);
|
|
1198
|
+
},
|
|
1199
|
+
},
|
|
1200
|
+
{
|
|
1201
|
+
name: 'claworld_update_public_identity',
|
|
1202
|
+
label: 'Claworld Update Public Identity',
|
|
1203
|
+
description: 'Set or update the public display name for the paired Claworld agent. On first setup, the backend will generate a stable unique code and return the final displayName#code identity.',
|
|
1204
|
+
metadata: buildToolMetadata({
|
|
1205
|
+
category: 'bootstrap',
|
|
1206
|
+
usageNotes: [
|
|
1207
|
+
'Use after the user confirms a public-facing name.',
|
|
1208
|
+
'On first setup, this generates the stable public code and completes identity readiness.',
|
|
1209
|
+
],
|
|
1210
|
+
}),
|
|
1211
|
+
parameters: objectParam({
|
|
1212
|
+
description: 'Update the public display name for one Claworld account.',
|
|
1213
|
+
required: ['accountId', 'displayName'],
|
|
1214
|
+
properties: {
|
|
1215
|
+
accountId: accountIdProperty,
|
|
1216
|
+
displayName: stringParam({
|
|
1217
|
+
description: 'Public-facing display name. # is reserved and must not appear here.',
|
|
1218
|
+
minLength: 1,
|
|
1219
|
+
examples: ['Moza', '小发发'],
|
|
1220
|
+
}),
|
|
1221
|
+
},
|
|
1222
|
+
}),
|
|
1223
|
+
async execute(_toolCallId, params = {}) {
|
|
1224
|
+
const context = await resolveToolContext(api, plugin, params);
|
|
1225
|
+
const payload = await plugin.runtime.productShell.profile.updatePublicIdentity({
|
|
1226
|
+
...context,
|
|
1227
|
+
displayName: params.displayName,
|
|
1228
|
+
});
|
|
1229
|
+
return buildToolResult(payload);
|
|
1230
|
+
},
|
|
1231
|
+
},
|
|
1126
1232
|
].map((tool) => ({
|
|
1127
1233
|
...tool,
|
|
1128
1234
|
execute: withToolErrorBoundary(tool.name, tool.execute),
|
|
@@ -1133,6 +1239,19 @@ export function registerClaworldPluginFull(api, plugin) {
|
|
|
1133
1239
|
if (!plugin) {
|
|
1134
1240
|
throw new Error('registerClaworldPluginFull requires a plugin instance');
|
|
1135
1241
|
}
|
|
1242
|
+
if (typeof api.on === 'function') {
|
|
1243
|
+
api.on('before_tool_call', async (event, ctx) => {
|
|
1244
|
+
if (event?.toolName !== 'claworld_request_chat') return;
|
|
1245
|
+
const requesterSessionKey = normalizeText(ctx?.sessionKey, null);
|
|
1246
|
+
if (!requesterSessionKey) return;
|
|
1247
|
+
return {
|
|
1248
|
+
params: {
|
|
1249
|
+
...(event?.params && typeof event.params === 'object' && !Array.isArray(event.params) ? event.params : {}),
|
|
1250
|
+
[INTERNAL_REQUESTER_SESSION_KEY_PARAM]: requesterSessionKey,
|
|
1251
|
+
},
|
|
1252
|
+
};
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1136
1255
|
if (typeof api.registerHttpRoute === 'function') {
|
|
1137
1256
|
api.registerHttpRoute(buildClaworldStatusRoute(plugin));
|
|
1138
1257
|
}
|