@xfxstudio/claworld 0.2.10-beta.3 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/src/openclaw/installer/cli.js +4 -2
- package/src/openclaw/installer/core.js +7 -1
- package/src/openclaw/installer/doctor.js +3 -3
- package/src/openclaw/plugin/claworld-channel-plugin.js +94 -9
- package/src/openclaw/plugin/onboarding.js +1 -1
- package/src/openclaw/plugin/register.js +210 -36
- package/src/openclaw/runtime/tool-inventory.js +1 -2
- package/src/product-shell/agent-cards/card-routes.js +64 -0
- package/src/product-shell/agent-cards/card-service.js +287 -0
- package/src/product-shell/agent-cards/spec-builder.js +167 -0
- package/src/product-shell/agent-cards/storage/image-host-storage.js +192 -0
- package/src/product-shell/agent-cards/storage/local-public-storage.js +74 -0
- package/src/product-shell/agent-cards/svg-renderer.js +325 -0
- package/src/product-shell/agent-cards/template-registry.js +131 -0
- package/src/product-shell/index.js +24 -3
- package/src/product-shell/onboarding/onboarding-service.js +4 -4
- package/src/product-shell/profile/profile-service.js +142 -0
- package/src/product-shell/profile/public-identity-routes.js +100 -0
- package/src/product-shell/profile/public-identity-service.js +4 -2
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -131,6 +131,7 @@ export function parseInstallerCliArgs(argv = process.argv.slice(2), env = proces
|
|
|
131
131
|
agentId: 'main',
|
|
132
132
|
workspace: null,
|
|
133
133
|
displayName: null,
|
|
134
|
+
pluginInstallSource: CLAWORLD_INSTALLER_DEFAULT_PLUGIN_SOURCE,
|
|
134
135
|
toolProfile: null,
|
|
135
136
|
},
|
|
136
137
|
doctor: {
|
|
@@ -234,6 +235,7 @@ export function parseInstallerCliArgs(argv = process.argv.slice(2), env = proces
|
|
|
234
235
|
break;
|
|
235
236
|
case '--plugin-source':
|
|
236
237
|
options.install.pluginInstallSource = nextValue(remaining, index);
|
|
238
|
+
options.update.pluginInstallSource = options.install.pluginInstallSource;
|
|
237
239
|
index += 1;
|
|
238
240
|
break;
|
|
239
241
|
case '--json':
|
|
@@ -298,7 +300,7 @@ function printInstallSummary(result) {
|
|
|
298
300
|
console.log(`Managed account: ${result.transformed?.config?.channels?.claworld?.defaultAccount || 'claworld'}`);
|
|
299
301
|
console.log(`OpenClaw version: ${result.host?.version || '(unknown)'}`);
|
|
300
302
|
console.log(`Plugin action: ${result.plugin?.action || 'unknown'}`);
|
|
301
|
-
console.log(`Activation: ${result.activationStatus === 'ready' ? 'ready' : 'pending via
|
|
303
|
+
console.log(`Activation: ${result.activationStatus === 'ready' ? 'ready' : 'pending via claworld_profile'}`);
|
|
302
304
|
console.log(`Runtime refresh: ${result.runtimeRefresh?.action || 'unknown'}`);
|
|
303
305
|
console.log(`Config path: ${result.configPath}`);
|
|
304
306
|
console.log(`Backup path: ${result.backupPath || '(unchanged or new file)'}`);
|
|
@@ -317,7 +319,7 @@ function printUpdateSummary(result, doctorResult) {
|
|
|
317
319
|
console.log(`OpenClaw version: ${result.host?.version || '(unknown)'}`);
|
|
318
320
|
console.log(`Plugin action: ${result.plugin?.action || 'unknown'}`);
|
|
319
321
|
console.log(`Tracked install: ${trackedSummary}`);
|
|
320
|
-
console.log(`Activation: ${result.activationStatus === 'ready' ? 'ready' : 'pending via
|
|
322
|
+
console.log(`Activation: ${result.activationStatus === 'ready' ? 'ready' : 'pending via claworld_profile'}`);
|
|
321
323
|
console.log(`Runtime refresh: ${result.runtimeRefresh?.action || 'unknown'}`);
|
|
322
324
|
console.log(`Doctor status: ${doctorResult?.status || 'unknown'}`);
|
|
323
325
|
console.log(`Config path: ${result.configPath}`);
|
|
@@ -1118,6 +1118,7 @@ export async function updateTrackedClaworldPluginInstall({
|
|
|
1118
1118
|
configPath = null,
|
|
1119
1119
|
stateDir = DEFAULT_OPENCLAW_STATE_DIR,
|
|
1120
1120
|
config = {},
|
|
1121
|
+
installSource = null,
|
|
1121
1122
|
commandRunner = defaultCommandRunner,
|
|
1122
1123
|
cwd = process.cwd(),
|
|
1123
1124
|
env = process.env,
|
|
@@ -1144,7 +1145,10 @@ export async function updateTrackedClaworldPluginInstall({
|
|
|
1144
1145
|
|
|
1145
1146
|
if (trackedInstall.source === 'installer_npm') {
|
|
1146
1147
|
const localInstall = await installPublishedClaworldPackageToLocalSource({
|
|
1147
|
-
installSource:
|
|
1148
|
+
installSource: normalizeText(
|
|
1149
|
+
installSource,
|
|
1150
|
+
trackedInstall.spec || CLAWORLD_INSTALLER_DEFAULT_PLUGIN_SOURCE,
|
|
1151
|
+
),
|
|
1148
1152
|
configPath,
|
|
1149
1153
|
commandRunner,
|
|
1150
1154
|
cwd,
|
|
@@ -1842,6 +1846,7 @@ export async function runClaworldInstallerUpdate({
|
|
|
1842
1846
|
agentId = DEFAULT_CLAWORLD_AGENT_ID,
|
|
1843
1847
|
workspace = null,
|
|
1844
1848
|
displayName = null,
|
|
1849
|
+
pluginInstallSource = null,
|
|
1845
1850
|
toolProfile = null,
|
|
1846
1851
|
approvalMode = null,
|
|
1847
1852
|
sessionDmScope = null,
|
|
@@ -1882,6 +1887,7 @@ export async function runClaworldInstallerUpdate({
|
|
|
1882
1887
|
configPath: resolvedConfigPath,
|
|
1883
1888
|
stateDir: resolvedStateDir,
|
|
1884
1889
|
config: currentConfigState.config,
|
|
1890
|
+
installSource: pluginInstallSource,
|
|
1885
1891
|
commandRunner,
|
|
1886
1892
|
cwd,
|
|
1887
1893
|
env,
|
|
@@ -528,7 +528,7 @@ export async function runClaworldDoctor({
|
|
|
528
528
|
: `Managed account token status is ${configuredAccount.tokenStatus}; activation is still pending.`,
|
|
529
529
|
action: configuredAccount.tokenStatus === 'available'
|
|
530
530
|
? null
|
|
531
|
-
: 'Open a live OpenClaw session, run `claworld_pair_agent`, and then complete `
|
|
531
|
+
: 'Open a live OpenClaw session, run `claworld_pair_agent`, and then complete `claworld_profile` with `action=update_identity` when prompted.',
|
|
532
532
|
details: { tokenSource: configuredAccount.tokenSource, tokenStatus: configuredAccount.tokenStatus },
|
|
533
533
|
}));
|
|
534
534
|
|
|
@@ -593,7 +593,7 @@ export async function runClaworldDoctor({
|
|
|
593
593
|
label: 'Stable relay binding',
|
|
594
594
|
status: 'warn',
|
|
595
595
|
summary: 'Doctor could not verify the managed relay binding because activation is still pending.',
|
|
596
|
-
action: 'Open a live OpenClaw session, run `claworld_pair_agent`, and then complete `
|
|
596
|
+
action: 'Open a live OpenClaw session, run `claworld_pair_agent`, and then complete `claworld_profile` with `action=update_identity` when prompted.',
|
|
597
597
|
}));
|
|
598
598
|
} else {
|
|
599
599
|
checks.push(createCheck({
|
|
@@ -676,7 +676,7 @@ export async function runClaworldDoctor({
|
|
|
676
676
|
action: channelHealthy
|
|
677
677
|
? null
|
|
678
678
|
: channelPendingActivation
|
|
679
|
-
? 'Open a live OpenClaw session, run `claworld_pair_agent`, and then complete `
|
|
679
|
+
? 'Open a live OpenClaw session, run `claworld_pair_agent`, and then complete `claworld_profile` with `action=update_identity` when prompted.'
|
|
680
680
|
: `Rerun \`${CLAWORLD_INSTALLER_COMMAND}\` or restart the gateway to recover the managed account runtime.`,
|
|
681
681
|
details: { channelAccount },
|
|
682
682
|
}));
|
|
@@ -908,6 +908,8 @@ async function fetchJson(fetchImpl, url, init = {}) {
|
|
|
908
908
|
async function fetchPublicIdentity({
|
|
909
909
|
runtimeConfig,
|
|
910
910
|
agentId = null,
|
|
911
|
+
generateShareCard = false,
|
|
912
|
+
expiresInSeconds = null,
|
|
911
913
|
fetchImpl,
|
|
912
914
|
}) {
|
|
913
915
|
if (!resolveRuntimeAppToken(runtimeConfig)) {
|
|
@@ -930,7 +932,7 @@ async function fetchPublicIdentity({
|
|
|
930
932
|
recommendedDisplayName,
|
|
931
933
|
nextAction: 'set_public_identity',
|
|
932
934
|
requiredAction: 'set_public_identity',
|
|
933
|
-
nextTool: '
|
|
935
|
+
nextTool: 'claworld_profile',
|
|
934
936
|
missingFields: [
|
|
935
937
|
{
|
|
936
938
|
fieldId: 'displayName',
|
|
@@ -953,15 +955,21 @@ async function fetchPublicIdentity({
|
|
|
953
955
|
}
|
|
954
956
|
|
|
955
957
|
const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
|
|
956
|
-
const
|
|
957
|
-
|
|
958
|
-
});
|
|
959
|
-
const result = await fetchJson(fetchImpl, `${baseUrl}${path}`, {
|
|
960
|
-
method: 'GET',
|
|
958
|
+
const result = await fetchJson(fetchImpl, `${baseUrl}/v1/profile`, {
|
|
959
|
+
method: 'POST',
|
|
961
960
|
headers: {
|
|
961
|
+
'content-type': 'application/json',
|
|
962
962
|
...(runtimeConfig.apiKey ? { 'x-api-key': runtimeConfig.apiKey } : {}),
|
|
963
963
|
...buildRuntimeAuthHeaders(runtimeConfig),
|
|
964
964
|
},
|
|
965
|
+
body: JSON.stringify({
|
|
966
|
+
...(agentId ? { agentId } : {}),
|
|
967
|
+
action: 'view',
|
|
968
|
+
...(generateShareCard === true ? { generateShareCard: true } : {}),
|
|
969
|
+
...(normalizeClaworldInteger(expiresInSeconds, null) > 0
|
|
970
|
+
? { expiresInSeconds: normalizeClaworldInteger(expiresInSeconds, null) }
|
|
971
|
+
: {}),
|
|
972
|
+
}),
|
|
965
973
|
});
|
|
966
974
|
if (!result.ok) {
|
|
967
975
|
createRelayRouteError({
|
|
@@ -979,6 +987,8 @@ async function updatePublicIdentity({
|
|
|
979
987
|
runtimeConfig,
|
|
980
988
|
agentId = null,
|
|
981
989
|
displayName = null,
|
|
990
|
+
generateShareCard = true,
|
|
991
|
+
expiresInSeconds = null,
|
|
982
992
|
fetchImpl,
|
|
983
993
|
}) {
|
|
984
994
|
const normalizedDisplayName = normalizeClaworldText(displayName, null);
|
|
@@ -1039,8 +1049,8 @@ async function updatePublicIdentity({
|
|
|
1039
1049
|
resolvedAgentId = activatedAgentId;
|
|
1040
1050
|
}
|
|
1041
1051
|
const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
|
|
1042
|
-
const result = await fetchJson(fetchImpl, `${baseUrl}/v1/profile
|
|
1043
|
-
method: '
|
|
1052
|
+
const result = await fetchJson(fetchImpl, `${baseUrl}/v1/profile`, {
|
|
1053
|
+
method: 'POST',
|
|
1044
1054
|
headers: {
|
|
1045
1055
|
'content-type': 'application/json',
|
|
1046
1056
|
...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
|
|
@@ -1048,7 +1058,12 @@ async function updatePublicIdentity({
|
|
|
1048
1058
|
},
|
|
1049
1059
|
body: JSON.stringify({
|
|
1050
1060
|
...(resolvedAgentId ? { agentId: resolvedAgentId } : {}),
|
|
1061
|
+
action: 'update_identity',
|
|
1051
1062
|
displayName: normalizedDisplayName,
|
|
1063
|
+
...(generateShareCard === true ? { generateShareCard: true } : {}),
|
|
1064
|
+
...(normalizeClaworldInteger(expiresInSeconds, null) > 0
|
|
1065
|
+
? { expiresInSeconds: normalizeClaworldInteger(expiresInSeconds, null) }
|
|
1066
|
+
: {}),
|
|
1052
1067
|
}),
|
|
1053
1068
|
});
|
|
1054
1069
|
if (!result.ok) {
|
|
@@ -1074,6 +1089,60 @@ async function updatePublicIdentity({
|
|
|
1074
1089
|
};
|
|
1075
1090
|
}
|
|
1076
1091
|
|
|
1092
|
+
async function renderAgentCard({
|
|
1093
|
+
runtimeConfig,
|
|
1094
|
+
agentId = null,
|
|
1095
|
+
expiresInSeconds = null,
|
|
1096
|
+
forceRegenerate = true,
|
|
1097
|
+
fetchImpl,
|
|
1098
|
+
}) {
|
|
1099
|
+
const resolvedAgentId = normalizeClaworldText(
|
|
1100
|
+
agentId,
|
|
1101
|
+
normalizeClaworldText(runtimeConfig?.relay?.agentId, null),
|
|
1102
|
+
);
|
|
1103
|
+
if (!resolvedAgentId) {
|
|
1104
|
+
throw createRuntimeBoundaryError({
|
|
1105
|
+
code: 'tool_input_invalid',
|
|
1106
|
+
category: 'input',
|
|
1107
|
+
status: 400,
|
|
1108
|
+
message: 'claworld profile card rendering requires agentId',
|
|
1109
|
+
publicMessage: 'claworld profile card rendering requires agentId',
|
|
1110
|
+
recoverable: true,
|
|
1111
|
+
context: { field: 'agentId' },
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
|
|
1116
|
+
const normalizedExpiresInSeconds = normalizeClaworldInteger(expiresInSeconds, null);
|
|
1117
|
+
const result = await fetchJson(fetchImpl, `${baseUrl}/v1/agent-cards/render`, {
|
|
1118
|
+
method: 'POST',
|
|
1119
|
+
headers: {
|
|
1120
|
+
'content-type': 'application/json',
|
|
1121
|
+
...(runtimeConfig.apiKey ? { 'x-api-key': runtimeConfig.apiKey } : {}),
|
|
1122
|
+
...buildRuntimeAuthHeaders(runtimeConfig),
|
|
1123
|
+
},
|
|
1124
|
+
body: JSON.stringify({
|
|
1125
|
+
agentId: resolvedAgentId,
|
|
1126
|
+
forceRegenerate: forceRegenerate === true,
|
|
1127
|
+
...(normalizedExpiresInSeconds && normalizedExpiresInSeconds > 0
|
|
1128
|
+
? { expiresInSeconds: normalizedExpiresInSeconds }
|
|
1129
|
+
: {}),
|
|
1130
|
+
}),
|
|
1131
|
+
});
|
|
1132
|
+
if (!result.ok) {
|
|
1133
|
+
createRelayRouteError({
|
|
1134
|
+
result,
|
|
1135
|
+
runtimeConfig,
|
|
1136
|
+
code: 'agent_card_render_failed',
|
|
1137
|
+
publicMessage: 'failed to generate public identity card',
|
|
1138
|
+
context: {
|
|
1139
|
+
agentId: resolvedAgentId,
|
|
1140
|
+
},
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
return result.body || {};
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1077
1146
|
async function registerRelayBinding({ runtimeConfig, fetchImpl, logger }) {
|
|
1078
1147
|
if (typeof fetchImpl !== 'function') {
|
|
1079
1148
|
throw new Error('fetch is unavailable for relay registration');
|
|
@@ -2443,6 +2512,8 @@ export function createClaworldChannelPlugin({
|
|
|
2443
2512
|
return fetchPublicIdentity({
|
|
2444
2513
|
runtimeConfig: resolvedContext.runtimeConfig,
|
|
2445
2514
|
agentId: resolvedContext.agentId || null,
|
|
2515
|
+
generateShareCard: context.generateShareCard === true,
|
|
2516
|
+
expiresInSeconds: context.expiresInSeconds ?? null,
|
|
2446
2517
|
fetchImpl,
|
|
2447
2518
|
});
|
|
2448
2519
|
}
|
|
@@ -2453,6 +2524,8 @@ export function createClaworldChannelPlugin({
|
|
|
2453
2524
|
runtimeConfig: resolvedContext.runtimeConfig,
|
|
2454
2525
|
agentId: resolvedContext.agentId || null,
|
|
2455
2526
|
displayName: context.displayName || null,
|
|
2527
|
+
generateShareCard: context.generateShareCard !== false,
|
|
2528
|
+
expiresInSeconds: context.expiresInSeconds ?? null,
|
|
2456
2529
|
fetchImpl,
|
|
2457
2530
|
});
|
|
2458
2531
|
|
|
@@ -2504,11 +2577,21 @@ export function createClaworldChannelPlugin({
|
|
|
2504
2577
|
const payload = updateResult && typeof updateResult === 'object' && !Array.isArray(updateResult)
|
|
2505
2578
|
? { ...updateResult }
|
|
2506
2579
|
: {};
|
|
2507
|
-
delete payload.runtimeActivation;
|
|
2508
2580
|
delete payload.runtimeConfig;
|
|
2509
2581
|
return payload;
|
|
2510
2582
|
}
|
|
2511
2583
|
|
|
2584
|
+
async function generateRuntimeProfileCard(context = {}) {
|
|
2585
|
+
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
2586
|
+
return renderAgentCard({
|
|
2587
|
+
runtimeConfig: resolvedContext.runtimeConfig,
|
|
2588
|
+
agentId: context.agentId || resolvedContext.agentId || null,
|
|
2589
|
+
expiresInSeconds: context.expiresInSeconds ?? null,
|
|
2590
|
+
forceRegenerate: context.forceRegenerate !== false,
|
|
2591
|
+
fetchImpl,
|
|
2592
|
+
});
|
|
2593
|
+
}
|
|
2594
|
+
|
|
2512
2595
|
return {
|
|
2513
2596
|
id: 'claworld',
|
|
2514
2597
|
meta: {
|
|
@@ -2763,6 +2846,7 @@ export function createClaworldChannelPlugin({
|
|
|
2763
2846
|
profile: {
|
|
2764
2847
|
getPublicIdentity: getRuntimePublicIdentity,
|
|
2765
2848
|
updatePublicIdentity: updateRuntimePublicIdentity,
|
|
2849
|
+
generateShareCard: generateRuntimeProfileCard,
|
|
2766
2850
|
},
|
|
2767
2851
|
postSetup: {
|
|
2768
2852
|
fetchWorldDirectory: async (context = {}) => {
|
|
@@ -2917,6 +3001,7 @@ export function createClaworldChannelPlugin({
|
|
|
2917
3001
|
profile: {
|
|
2918
3002
|
getPublicIdentity: getRuntimePublicIdentity,
|
|
2919
3003
|
updatePublicIdentity: updateRuntimePublicIdentity,
|
|
3004
|
+
generateShareCard: generateRuntimeProfileCard,
|
|
2920
3005
|
},
|
|
2921
3006
|
fetchWorldDirectory: async (context = {}) => {
|
|
2922
3007
|
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
@@ -201,7 +201,7 @@ async function applyManagedOnboardingConfig({
|
|
|
201
201
|
`Remote backend: ${managedOptions.serverUrl}`,
|
|
202
202
|
managedOptions.appToken
|
|
203
203
|
? 'Activation state: ready via configured appToken'
|
|
204
|
-
: 'Activation state: pending until
|
|
204
|
+
: 'Activation state: pending until claworld_profile runs',
|
|
205
205
|
managedOptions.manageWorkspace
|
|
206
206
|
? 'This flow refreshes plugin-side config and the dedicated claworld workspace contract. It does not start a backend service.'
|
|
207
207
|
: 'This flow refreshes plugin-side config and binds claworld onto the existing local agent. It does not start a backend service.',
|
|
@@ -239,6 +239,17 @@ function integerParam({
|
|
|
239
239
|
};
|
|
240
240
|
}
|
|
241
241
|
|
|
242
|
+
function booleanParam({
|
|
243
|
+
description = null,
|
|
244
|
+
defaultValue = null,
|
|
245
|
+
} = {}) {
|
|
246
|
+
return {
|
|
247
|
+
type: 'boolean',
|
|
248
|
+
...(description ? { description } : {}),
|
|
249
|
+
...(typeof defaultValue === 'boolean' ? { default: defaultValue } : {}),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
242
253
|
function objectParam({
|
|
243
254
|
description = null,
|
|
244
255
|
properties = {},
|
|
@@ -337,6 +348,118 @@ function projectToolManageWorldActionResponse(payload = {}, { accountId = null,
|
|
|
337
348
|
};
|
|
338
349
|
}
|
|
339
350
|
|
|
351
|
+
const PROFILE_ACTIONS = Object.freeze([
|
|
352
|
+
'view',
|
|
353
|
+
'update_identity',
|
|
354
|
+
]);
|
|
355
|
+
|
|
356
|
+
function normalizeProfileAction(value, fallback = null) {
|
|
357
|
+
const normalized = normalizeText(value, fallback);
|
|
358
|
+
return PROFILE_ACTIONS.includes(normalized) ? normalized : fallback;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function inferProfileAction(params = {}) {
|
|
362
|
+
const explicitAction = normalizeProfileAction(params.action, null);
|
|
363
|
+
if (explicitAction) return explicitAction;
|
|
364
|
+
if (normalizeText(params.displayName, null)) return 'update_identity';
|
|
365
|
+
return 'view';
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function projectToolPublicIdentity(payload = null) {
|
|
369
|
+
if (!payload || typeof payload !== 'object') return null;
|
|
370
|
+
return {
|
|
371
|
+
status: payload.status || null,
|
|
372
|
+
ready: payload.ready ?? null,
|
|
373
|
+
publicIdentity: payload.publicIdentity && typeof payload.publicIdentity === 'object'
|
|
374
|
+
? {
|
|
375
|
+
status: payload.publicIdentity.status || null,
|
|
376
|
+
displayIdentity: payload.publicIdentity.displayIdentity || null,
|
|
377
|
+
displayName: payload.publicIdentity.displayName || null,
|
|
378
|
+
code: payload.publicIdentity.code || null,
|
|
379
|
+
confirmedAt: payload.publicIdentity.confirmedAt || null,
|
|
380
|
+
updatedAt: payload.publicIdentity.updatedAt || null,
|
|
381
|
+
}
|
|
382
|
+
: null,
|
|
383
|
+
recommendedDisplayName: payload.recommendedDisplayName || null,
|
|
384
|
+
requiredAction: payload.requiredAction || null,
|
|
385
|
+
nextAction: payload.nextAction || null,
|
|
386
|
+
nextTool: payload.nextTool || null,
|
|
387
|
+
missingFields: Array.isArray(payload.missingFields) ? payload.missingFields : [],
|
|
388
|
+
feedbackSummary: payload.feedbackSummary && typeof payload.feedbackSummary === 'object'
|
|
389
|
+
? {
|
|
390
|
+
totalLikesReceived: Number(payload.feedbackSummary.totalLikesReceived || 0),
|
|
391
|
+
totalDislikesReceived: Number(payload.feedbackSummary.totalDislikesReceived || 0),
|
|
392
|
+
totalLikesGiven: Number(payload.feedbackSummary.totalLikesGiven || 0),
|
|
393
|
+
totalDislikesGiven: Number(payload.feedbackSummary.totalDislikesGiven || 0),
|
|
394
|
+
}
|
|
395
|
+
: null,
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function projectToolShareCard(payload = null) {
|
|
400
|
+
const card = payload?.card && typeof payload.card === 'object' ? payload.card : null;
|
|
401
|
+
const imageUrl = normalizeText(card?.imageUrl, normalizeText(payload?.imageUrl, null));
|
|
402
|
+
const downloadUrl = normalizeText(card?.downloadUrl, normalizeText(payload?.downloadUrl, imageUrl));
|
|
403
|
+
const templateId = normalizeText(card?.templateId, normalizeText(payload?.templateId, null));
|
|
404
|
+
const expiresAt = normalizeText(card?.expiresAt, normalizeText(payload?.expiresAt, null));
|
|
405
|
+
const description = normalizeText(card?.description, normalizeText(payload?.description, null));
|
|
406
|
+
if (!imageUrl && !downloadUrl && !templateId && !expiresAt && !description) {
|
|
407
|
+
return {
|
|
408
|
+
status: normalizeText(payload?.status, 'unavailable'),
|
|
409
|
+
reason: normalizeText(payload?.reason, null),
|
|
410
|
+
message: normalizeText(payload?.message, null),
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
return {
|
|
414
|
+
status: normalizeText(payload?.status, 'ready'),
|
|
415
|
+
imageUrl,
|
|
416
|
+
downloadUrl,
|
|
417
|
+
templateId,
|
|
418
|
+
expiresAt,
|
|
419
|
+
description,
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function projectToolProfileResponse({
|
|
424
|
+
action = 'view',
|
|
425
|
+
accountId = null,
|
|
426
|
+
identityPayload = null,
|
|
427
|
+
shareCard = undefined,
|
|
428
|
+
runtimeActivation = null,
|
|
429
|
+
} = {}) {
|
|
430
|
+
const projectedIdentity = projectToolPublicIdentity(identityPayload);
|
|
431
|
+
const resolvedShareCard = shareCard !== undefined
|
|
432
|
+
? shareCard
|
|
433
|
+
: (identityPayload && Object.prototype.hasOwnProperty.call(identityPayload, 'shareCard')
|
|
434
|
+
? projectToolShareCard(identityPayload.shareCard)
|
|
435
|
+
: undefined);
|
|
436
|
+
const ready = projectedIdentity?.ready === true;
|
|
437
|
+
return {
|
|
438
|
+
action,
|
|
439
|
+
status: ready ? 'ready' : 'pending',
|
|
440
|
+
ready,
|
|
441
|
+
accountId: normalizeText(accountId, null),
|
|
442
|
+
...(projectedIdentity || {
|
|
443
|
+
publicIdentity: null,
|
|
444
|
+
recommendedDisplayName: null,
|
|
445
|
+
requiredAction: null,
|
|
446
|
+
nextAction: null,
|
|
447
|
+
nextTool: null,
|
|
448
|
+
missingFields: [],
|
|
449
|
+
feedbackSummary: null,
|
|
450
|
+
}),
|
|
451
|
+
...(resolvedShareCard !== undefined ? { shareCard: resolvedShareCard } : {}),
|
|
452
|
+
...(runtimeActivation ? { runtimeActivation } : {}),
|
|
453
|
+
...(action === 'update_identity'
|
|
454
|
+
? {
|
|
455
|
+
updated: resolvedShareCard && resolvedShareCard.status === 'ready'
|
|
456
|
+
? ['publicIdentity', 'shareCard']
|
|
457
|
+
: ['publicIdentity'],
|
|
458
|
+
}
|
|
459
|
+
: {}),
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
|
|
340
463
|
function buildRegisteredTools(api, plugin) {
|
|
341
464
|
const accountIdProperty = stringParam({
|
|
342
465
|
description: 'Claworld account id to execute the tool against. In managed installs this is usually the dedicated claworld account.',
|
|
@@ -1145,7 +1268,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1145
1268
|
reason: payload.reason || null,
|
|
1146
1269
|
requiredAction: publicIdentity?.requiredAction || (ready ? null : 'set_public_identity'),
|
|
1147
1270
|
nextAction: publicIdentity?.nextAction || (ready ? 'continue_claworld_flow' : 'set_public_identity'),
|
|
1148
|
-
nextTool: publicIdentity?.nextTool || (ready ? null : '
|
|
1271
|
+
nextTool: publicIdentity?.nextTool || (ready ? null : 'claworld_profile'),
|
|
1149
1272
|
missingFields: Array.isArray(publicIdentity?.missingFields) ? publicIdentity.missingFields : [],
|
|
1150
1273
|
accountId: payload.runtimeConfig?.accountId || accountId,
|
|
1151
1274
|
bindingSource: payload.bindingSource || null,
|
|
@@ -1186,59 +1309,110 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1186
1309
|
},
|
|
1187
1310
|
},
|
|
1188
1311
|
{
|
|
1189
|
-
name: '
|
|
1190
|
-
label: 'Claworld
|
|
1191
|
-
description: '
|
|
1312
|
+
name: 'claworld_profile',
|
|
1313
|
+
label: 'Claworld Profile',
|
|
1314
|
+
description: 'View or update the paired Claworld public profile. This surface covers public identity readiness and, when requested, generates a temporary public identity card for sharing.',
|
|
1192
1315
|
metadata: buildToolMetadata({
|
|
1193
|
-
category: '
|
|
1316
|
+
category: 'profile',
|
|
1194
1317
|
usageNotes: [
|
|
1195
|
-
'
|
|
1196
|
-
'Use
|
|
1318
|
+
'Default action is view; omit action to inspect the current public identity state.',
|
|
1319
|
+
'Use action=update_identity after the user confirms a public-facing display name.',
|
|
1320
|
+
'Set generateShareCard=true to return a temporary public identity card URL.',
|
|
1197
1321
|
],
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
category: 'bootstrap',
|
|
1218
|
-
usageNotes: [
|
|
1219
|
-
'Use after the user confirms a public-facing name.',
|
|
1220
|
-
'On first setup, this generates the stable public code and completes identity readiness.',
|
|
1322
|
+
examples: [
|
|
1323
|
+
{
|
|
1324
|
+
title: 'View the current profile state',
|
|
1325
|
+
input: {
|
|
1326
|
+
accountId: 'claworld',
|
|
1327
|
+
action: 'view',
|
|
1328
|
+
},
|
|
1329
|
+
outcome: 'Returns the current public identity and readiness state.',
|
|
1330
|
+
},
|
|
1331
|
+
{
|
|
1332
|
+
title: 'Update public identity and return a share card',
|
|
1333
|
+
input: {
|
|
1334
|
+
accountId: 'claworld',
|
|
1335
|
+
action: 'update_identity',
|
|
1336
|
+
displayName: '小发发',
|
|
1337
|
+
generateShareCard: true,
|
|
1338
|
+
},
|
|
1339
|
+
outcome: 'Persists the display name, keeps the stable code, and returns a temporary share-card URL.',
|
|
1340
|
+
},
|
|
1221
1341
|
],
|
|
1222
1342
|
}),
|
|
1223
1343
|
parameters: objectParam({
|
|
1224
|
-
description: '
|
|
1225
|
-
required: ['accountId'
|
|
1344
|
+
description: 'View or update the public profile for one Claworld account.',
|
|
1345
|
+
required: ['accountId'],
|
|
1226
1346
|
properties: {
|
|
1227
1347
|
accountId: accountIdProperty,
|
|
1348
|
+
action: stringParam({
|
|
1349
|
+
description: 'Profile action. Defaults to view; inferred as update_identity when displayName is present.',
|
|
1350
|
+
enumValues: PROFILE_ACTIONS,
|
|
1351
|
+
examples: ['view', 'update_identity'],
|
|
1352
|
+
}),
|
|
1228
1353
|
displayName: stringParam({
|
|
1229
|
-
description: 'Public-facing display name. # is reserved and must not appear here.',
|
|
1354
|
+
description: 'Public-facing display name. Required for action=update_identity. # is reserved and must not appear here.',
|
|
1230
1355
|
minLength: 1,
|
|
1231
1356
|
examples: ['Moza', '小发发'],
|
|
1232
1357
|
}),
|
|
1358
|
+
generateShareCard: booleanParam({
|
|
1359
|
+
description: 'When true, return a temporary public identity card URL. Defaults to false for view and true for update_identity.',
|
|
1360
|
+
}),
|
|
1361
|
+
expiresInSeconds: integerParam({
|
|
1362
|
+
description: 'Optional temporary share-card TTL in seconds.',
|
|
1363
|
+
minimum: 1,
|
|
1364
|
+
examples: [7200],
|
|
1365
|
+
}),
|
|
1233
1366
|
},
|
|
1367
|
+
examples: [
|
|
1368
|
+
{
|
|
1369
|
+
accountId: 'claworld',
|
|
1370
|
+
action: 'view',
|
|
1371
|
+
},
|
|
1372
|
+
{
|
|
1373
|
+
accountId: 'claworld',
|
|
1374
|
+
action: 'update_identity',
|
|
1375
|
+
displayName: '小发发',
|
|
1376
|
+
generateShareCard: true,
|
|
1377
|
+
},
|
|
1378
|
+
],
|
|
1234
1379
|
}),
|
|
1235
1380
|
async execute(_toolCallId, params = {}) {
|
|
1236
1381
|
const context = await resolveToolContext(api, plugin, params, { bindRuntime: false });
|
|
1237
|
-
const
|
|
1382
|
+
const action = inferProfileAction(params);
|
|
1383
|
+
const generateShareCard = typeof params.generateShareCard === 'boolean'
|
|
1384
|
+
? params.generateShareCard
|
|
1385
|
+
: action === 'update_identity';
|
|
1386
|
+
|
|
1387
|
+
if (action === 'update_identity') {
|
|
1388
|
+
const displayName = normalizeText(params.displayName, null);
|
|
1389
|
+
if (!displayName) {
|
|
1390
|
+
requireManageWorldField('displayName', 'displayName is required for action=update_identity');
|
|
1391
|
+
}
|
|
1392
|
+
const payload = await plugin.runtime.productShell.profile.updatePublicIdentity({
|
|
1393
|
+
...context,
|
|
1394
|
+
displayName,
|
|
1395
|
+
generateShareCard,
|
|
1396
|
+
expiresInSeconds: params.expiresInSeconds ?? null,
|
|
1397
|
+
});
|
|
1398
|
+
return buildToolResult(projectToolProfileResponse({
|
|
1399
|
+
action,
|
|
1400
|
+
accountId: context.accountId,
|
|
1401
|
+
identityPayload: payload,
|
|
1402
|
+
runtimeActivation: payload?.runtimeActivation || null,
|
|
1403
|
+
}));
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
const payload = await plugin.runtime.productShell.profile.getPublicIdentity({
|
|
1238
1407
|
...context,
|
|
1239
|
-
|
|
1408
|
+
generateShareCard,
|
|
1409
|
+
expiresInSeconds: params.expiresInSeconds ?? null,
|
|
1240
1410
|
});
|
|
1241
|
-
return buildToolResult(
|
|
1411
|
+
return buildToolResult(projectToolProfileResponse({
|
|
1412
|
+
action,
|
|
1413
|
+
accountId: context.accountId,
|
|
1414
|
+
identityPayload: payload,
|
|
1415
|
+
}));
|
|
1242
1416
|
},
|
|
1243
1417
|
},
|
|
1244
1418
|
].map((tool) => ({
|
|
@@ -12,8 +12,7 @@ export const CLAWORLD_BOOTSTRAP_TOOL_NAMES = Object.freeze([
|
|
|
12
12
|
]);
|
|
13
13
|
|
|
14
14
|
export const CLAWORLD_PROFILE_TOOL_NAMES = Object.freeze([
|
|
15
|
-
'
|
|
16
|
-
'claworld_update_public_identity',
|
|
15
|
+
'claworld_profile',
|
|
17
16
|
]);
|
|
18
17
|
|
|
19
18
|
export const CLAWORLD_FEEDBACK_TOOL_NAMES = Object.freeze([
|