@xfxstudio/claworld 0.2.14 → 0.2.16
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/bin/claworld.mjs +9 -0
- package/openclaw.plugin.json +1 -97
- package/package.json +5 -1
- package/skills/claworld-help/SKILL.md +126 -88
- package/skills/claworld-join-and-chat/SKILL.md +205 -100
- package/skills/claworld-manage-worlds/SKILL.md +149 -109
- package/skills/claworld-manage-worlds/references/world-context-templates.md +145 -0
- package/src/lib/relay/kickoff-text.js +49 -21
- package/src/openclaw/installer/cli.js +406 -0
- package/src/openclaw/installer/constants.js +14 -0
- package/src/openclaw/installer/core.js +2115 -0
- package/src/openclaw/installer/doctor.js +876 -0
- package/src/openclaw/installer/workspace-contract.js +427 -0
- package/src/openclaw/plugin/claworld-channel-plugin.js +214 -223
- package/src/openclaw/plugin/config-schema.js +1 -55
- package/src/openclaw/plugin/managed-config.js +0 -35
- package/src/openclaw/plugin/register-tooling.js +556 -0
- package/src/openclaw/plugin/register.js +218 -532
- package/src/openclaw/plugin/relay-client-shared.js +146 -0
- package/src/openclaw/plugin/relay-client.js +27 -151
- package/src/openclaw/runtime/product-shell-helper.js +14 -142
- package/src/openclaw/runtime/tool-contracts.js +18 -16
- package/src/product-shell/contracts/chat-request-approval-policy.js +2 -7
- package/src/product-shell/contracts/world-orchestration.js +17 -71
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { createClaworldChannelPlugin } from './claworld-channel-plugin.js';
|
|
2
2
|
import {
|
|
3
|
-
projectToolChatInboxResponse,
|
|
4
3
|
projectToolChatRequestMutationResponse,
|
|
5
4
|
projectToolCreateWorldResponse,
|
|
6
|
-
projectToolManagedWorldResponse,
|
|
7
|
-
projectToolOwnedWorldsResponse,
|
|
8
5
|
projectToolWorldList,
|
|
9
6
|
projectToolFeedbackSubmissionResponse,
|
|
10
7
|
projectToolJoinWorldResponse,
|
|
@@ -13,78 +10,36 @@ import {
|
|
|
13
10
|
import { CLAWORLD_TOOL_CONTRACT_VERSION } from '../runtime/tool-inventory.js';
|
|
14
11
|
import { setClaworldRuntime } from './runtime.js';
|
|
15
12
|
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
normalizeRuntimeBoundaryError,
|
|
20
|
-
} from '../../lib/runtime-errors.js';
|
|
13
|
+
CHAT_REQUEST_APPROVAL_POLICY_MODES,
|
|
14
|
+
CHAT_REQUEST_APPROVAL_POLICY_ORIGIN_TYPES,
|
|
15
|
+
} from '../../product-shell/contracts/chat-request-approval-policy.js';
|
|
21
16
|
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
...(code ? { code } : {}),
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function buildPublicToolErrorExtras(error) {
|
|
53
|
-
const context = normalizeObject(error?.context, null);
|
|
54
|
-
if (!context) return null;
|
|
55
|
-
|
|
56
|
-
const httpStatus = Number(context.httpStatus);
|
|
57
|
-
const backendCode = normalizeText(context.backendCode, null);
|
|
58
|
-
const backendMessage = normalizeText(context.backendMessage, null);
|
|
59
|
-
const fieldErrors = Array.isArray(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)
|
|
71
|
-
: [];
|
|
72
|
-
const publicIdentity = normalizeBackendPublicIdentity(context.publicIdentity);
|
|
73
|
-
|
|
74
|
-
const extra = {
|
|
75
|
-
...(Number.isInteger(httpStatus) && httpStatus > 0 ? { httpStatus } : {}),
|
|
76
|
-
...(backendCode ? { backendCode } : {}),
|
|
77
|
-
...(backendMessage ? { backendMessage } : {}),
|
|
78
|
-
...(fieldErrors.length > 0 ? { fieldErrors } : {}),
|
|
79
|
-
...(requiredAction ? { requiredAction } : {}),
|
|
80
|
-
...(nextAction ? { nextAction } : {}),
|
|
81
|
-
...(nextTool ? { nextTool } : {}),
|
|
82
|
-
...(missingFields.length > 0 ? { missingFields } : {}),
|
|
83
|
-
...(publicIdentity ? { publicIdentity } : {}),
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
return Object.keys(extra).length > 0 ? extra : null;
|
|
87
|
-
}
|
|
17
|
+
ACCOUNT_ACTIONS,
|
|
18
|
+
arrayParam,
|
|
19
|
+
booleanParam,
|
|
20
|
+
buildToolMetadata,
|
|
21
|
+
buildToolResult,
|
|
22
|
+
CHAT_INBOX_ACTIONS,
|
|
23
|
+
inferAccountAction,
|
|
24
|
+
inferChatInboxAction,
|
|
25
|
+
inferManageWorldAction,
|
|
26
|
+
INTERNAL_REQUESTER_SESSION_KEY_PARAM,
|
|
27
|
+
integerParam,
|
|
28
|
+
loadCurrentConfig,
|
|
29
|
+
MANAGE_WORLD_ACTIONS,
|
|
30
|
+
normalizeManageWorldAction,
|
|
31
|
+
normalizeObject,
|
|
32
|
+
normalizeText,
|
|
33
|
+
objectParam,
|
|
34
|
+
projectToolAccountMutationResponse,
|
|
35
|
+
projectToolAccountViewResponse,
|
|
36
|
+
projectToolChatInboxActionResponse,
|
|
37
|
+
projectToolManageWorldActionResponse,
|
|
38
|
+
requireManageWorldField,
|
|
39
|
+
resolveToolContext,
|
|
40
|
+
stringParam,
|
|
41
|
+
withToolErrorBoundary,
|
|
42
|
+
} from './register-tooling.js';
|
|
88
43
|
|
|
89
44
|
function buildClaworldStatusRoute(plugin) {
|
|
90
45
|
return {
|
|
@@ -114,442 +69,49 @@ function buildClaworldStatusRoute(plugin) {
|
|
|
114
69
|
};
|
|
115
70
|
}
|
|
116
71
|
|
|
117
|
-
async function loadCurrentConfig(api) {
|
|
118
|
-
if (api?.config && typeof api.config.loadConfig === 'function') {
|
|
119
|
-
return await api.config.loadConfig();
|
|
120
|
-
}
|
|
121
|
-
if (api?.runtime?.config && typeof api.runtime.config.loadConfig === 'function') {
|
|
122
|
-
return await api.runtime.config.loadConfig();
|
|
123
|
-
}
|
|
124
|
-
if (api?.config && typeof api.config === 'object') {
|
|
125
|
-
return api.config;
|
|
126
|
-
}
|
|
127
|
-
return {};
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function buildToolResult(payload) {
|
|
131
|
-
return {
|
|
132
|
-
content: [
|
|
133
|
-
{
|
|
134
|
-
type: 'text',
|
|
135
|
-
text: JSON.stringify(payload, null, 2),
|
|
136
|
-
},
|
|
137
|
-
],
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function buildToolErrorResult(toolName, error) {
|
|
142
|
-
const normalized = normalizeRuntimeBoundaryError(error, {
|
|
143
|
-
code: 'claworld_tool_execution_failed',
|
|
144
|
-
category: 'runtime',
|
|
145
|
-
publicMessage: 'tool execution failed',
|
|
146
|
-
recoverable: true,
|
|
147
|
-
});
|
|
148
|
-
return buildToolResult({
|
|
149
|
-
status: 'error',
|
|
150
|
-
tool: toolName,
|
|
151
|
-
...buildPublicErrorPayload(normalized, {
|
|
152
|
-
errorType: 'claworld_tool_failed',
|
|
153
|
-
fallbackMessage: 'tool execution failed',
|
|
154
|
-
exposeMessage: normalized.status < 500 || Boolean(normalized.publicMessage),
|
|
155
|
-
extra: buildPublicToolErrorExtras(normalized),
|
|
156
|
-
}),
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function withToolErrorBoundary(toolName, execute) {
|
|
161
|
-
return async (toolCallId, params = {}) => {
|
|
162
|
-
try {
|
|
163
|
-
return await execute(toolCallId, params);
|
|
164
|
-
} catch (error) {
|
|
165
|
-
const normalized = logRuntimeBoundary(console, `[claworld:tool:${toolName}] execution failed`, error, {
|
|
166
|
-
tool: toolName,
|
|
167
|
-
}, {
|
|
168
|
-
includeStack: false,
|
|
169
|
-
fallback: {
|
|
170
|
-
code: 'claworld_tool_execution_failed',
|
|
171
|
-
category: 'runtime',
|
|
172
|
-
publicMessage: 'tool execution failed',
|
|
173
|
-
recoverable: true,
|
|
174
|
-
},
|
|
175
|
-
});
|
|
176
|
-
return buildToolErrorResult(toolName, normalized);
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
async function resolveToolContext(api, plugin, params = {}, { bindRuntime = true } = {}) {
|
|
182
|
-
const cfg = await loadCurrentConfig(api);
|
|
183
|
-
const accountId = normalizeText(params.accountId, plugin.config.defaultAccountId(cfg) || null);
|
|
184
|
-
const runtimeConfig = plugin.config.resolveRuntimeConfig(cfg, accountId);
|
|
185
|
-
|
|
186
|
-
if (bindRuntime && typeof plugin.helpers?.resolveToolRuntimeContext === 'function') {
|
|
187
|
-
return await plugin.helpers.resolveToolRuntimeContext({
|
|
188
|
-
cfg,
|
|
189
|
-
accountId,
|
|
190
|
-
runtimeConfig,
|
|
191
|
-
agentId: normalizeText(params.agentId, runtimeConfig.relay?.agentId || null),
|
|
192
|
-
requesterSessionKey: normalizeText(params[INTERNAL_REQUESTER_SESSION_KEY_PARAM], null),
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const agentId = normalizeText(params.agentId, runtimeConfig.relay?.agentId || null);
|
|
197
|
-
return {
|
|
198
|
-
cfg,
|
|
199
|
-
accountId,
|
|
200
|
-
runtimeConfig,
|
|
201
|
-
agentId,
|
|
202
|
-
requesterSessionKey: normalizeText(params[INTERNAL_REQUESTER_SESSION_KEY_PARAM], null),
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
function cloneMetadataValue(value) {
|
|
207
|
-
return value == null ? value : JSON.parse(JSON.stringify(value));
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
function stringParam({
|
|
211
|
-
description = null,
|
|
212
|
-
minLength = null,
|
|
213
|
-
enumValues = null,
|
|
214
|
-
pattern = null,
|
|
215
|
-
examples = [],
|
|
216
|
-
} = {}) {
|
|
217
|
-
return {
|
|
218
|
-
type: 'string',
|
|
219
|
-
...(description ? { description } : {}),
|
|
220
|
-
...(Number.isInteger(minLength) && minLength > 0 ? { minLength } : {}),
|
|
221
|
-
...(Array.isArray(enumValues) && enumValues.length > 0 ? { enum: enumValues } : {}),
|
|
222
|
-
...(pattern ? { pattern } : {}),
|
|
223
|
-
...(Array.isArray(examples) && examples.length > 0 ? { examples } : {}),
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
function integerParam({
|
|
228
|
-
description = null,
|
|
229
|
-
minimum = null,
|
|
230
|
-
maximum = null,
|
|
231
|
-
examples = [],
|
|
232
|
-
} = {}) {
|
|
233
|
-
return {
|
|
234
|
-
type: 'integer',
|
|
235
|
-
...(description ? { description } : {}),
|
|
236
|
-
...(Number.isInteger(minimum) ? { minimum } : {}),
|
|
237
|
-
...(Number.isInteger(maximum) ? { maximum } : {}),
|
|
238
|
-
...(Array.isArray(examples) && examples.length > 0 ? { examples } : {}),
|
|
239
|
-
};
|
|
240
|
-
}
|
|
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
|
-
|
|
253
|
-
function objectParam({
|
|
254
|
-
description = null,
|
|
255
|
-
properties = {},
|
|
256
|
-
required = [],
|
|
257
|
-
additionalProperties = false,
|
|
258
|
-
examples = [],
|
|
259
|
-
} = {}) {
|
|
260
|
-
return {
|
|
261
|
-
type: 'object',
|
|
262
|
-
additionalProperties,
|
|
263
|
-
...(description ? { description } : {}),
|
|
264
|
-
...(Array.isArray(required) && required.length > 0 ? { required } : {}),
|
|
265
|
-
properties,
|
|
266
|
-
...(Array.isArray(examples) && examples.length > 0 ? { examples: examples.map(cloneMetadataValue) } : {}),
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
function arrayParam({
|
|
271
|
-
description = null,
|
|
272
|
-
items = {},
|
|
273
|
-
maxItems = null,
|
|
274
|
-
examples = [],
|
|
275
|
-
} = {}) {
|
|
276
|
-
return {
|
|
277
|
-
type: 'array',
|
|
278
|
-
items,
|
|
279
|
-
...(description ? { description } : {}),
|
|
280
|
-
...(Number.isInteger(maxItems) ? { maxItems } : {}),
|
|
281
|
-
...(Array.isArray(examples) && examples.length > 0 ? { examples: examples.map(cloneMetadataValue) } : {}),
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
function buildToolMetadata({
|
|
286
|
-
category,
|
|
287
|
-
usageNotes = [],
|
|
288
|
-
examples = [],
|
|
289
|
-
} = {}) {
|
|
290
|
-
return {
|
|
291
|
-
surface: 'canonical_public',
|
|
292
|
-
canonical: true,
|
|
293
|
-
category: normalizeText(category, 'general'),
|
|
294
|
-
usageNotes: Array.isArray(usageNotes) ? usageNotes.filter(Boolean) : [],
|
|
295
|
-
examples: Array.isArray(examples)
|
|
296
|
-
? examples.map((example) => cloneMetadataValue(example)).filter(Boolean)
|
|
297
|
-
: [],
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
const MANAGE_WORLD_ACTIONS = Object.freeze([
|
|
302
|
-
'list',
|
|
303
|
-
'get',
|
|
304
|
-
'update_context',
|
|
305
|
-
'pause',
|
|
306
|
-
'close',
|
|
307
|
-
'resume',
|
|
308
|
-
]);
|
|
309
|
-
|
|
310
|
-
function normalizeManageWorldAction(value, fallback = null) {
|
|
311
|
-
const normalized = normalizeText(value, fallback);
|
|
312
|
-
return MANAGE_WORLD_ACTIONS.includes(normalized) ? normalized : fallback;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
function inferManageWorldAction(params = {}) {
|
|
316
|
-
const explicitAction = normalizeManageWorldAction(params.action, null);
|
|
317
|
-
if (explicitAction) return explicitAction;
|
|
318
|
-
if (!normalizeText(params.worldId, null)) return 'list';
|
|
319
|
-
if (normalizeText(params.worldContextText, null) || normalizeText(params.displayName, null)) {
|
|
320
|
-
return 'update_context';
|
|
321
|
-
}
|
|
322
|
-
return 'get';
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
function requireManageWorldField(fieldId, message = `${fieldId} is required`) {
|
|
326
|
-
throw createRuntimeBoundaryError({
|
|
327
|
-
code: 'tool_input_invalid',
|
|
328
|
-
category: 'input',
|
|
329
|
-
status: 400,
|
|
330
|
-
message,
|
|
331
|
-
publicMessage: message,
|
|
332
|
-
recoverable: true,
|
|
333
|
-
context: { field: fieldId },
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
function projectToolManageWorldActionResponse(payload = {}, { accountId = null, action = null } = {}) {
|
|
338
|
-
const resolvedAction = normalizeManageWorldAction(action, null) || 'get';
|
|
339
|
-
if (resolvedAction === 'list') {
|
|
340
|
-
return {
|
|
341
|
-
action: resolvedAction,
|
|
342
|
-
...projectToolOwnedWorldsResponse(payload, { accountId }),
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
|
-
return {
|
|
346
|
-
action: resolvedAction,
|
|
347
|
-
...projectToolManagedWorldResponse(payload, { accountId }),
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
const CHAT_INBOX_ACTIONS = Object.freeze([
|
|
352
|
-
'list',
|
|
353
|
-
'accept',
|
|
354
|
-
'reject',
|
|
355
|
-
]);
|
|
356
|
-
|
|
357
|
-
function normalizeChatInboxAction(value, fallback = null) {
|
|
358
|
-
const normalized = normalizeText(value, fallback);
|
|
359
|
-
return CHAT_INBOX_ACTIONS.includes(normalized) ? normalized : fallback;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
function inferChatInboxAction(params = {}) {
|
|
363
|
-
return normalizeChatInboxAction(params.action, 'list');
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
function projectToolChatInboxActionResponse(payload = {}, { accountId = null, action = 'list' } = {}) {
|
|
367
|
-
const resolvedAction = normalizeChatInboxAction(action, 'list');
|
|
368
|
-
if (resolvedAction === 'list') {
|
|
369
|
-
return {
|
|
370
|
-
action: resolvedAction,
|
|
371
|
-
...projectToolChatInboxResponse(payload, { accountId }),
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
return {
|
|
375
|
-
action: resolvedAction,
|
|
376
|
-
...projectToolChatRequestMutationResponse(payload, { accountId }),
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
const ACCOUNT_ACTIONS = Object.freeze([
|
|
381
|
-
'view',
|
|
382
|
-
'update_identity',
|
|
383
|
-
]);
|
|
384
|
-
|
|
385
|
-
function normalizeAccountAction(value, fallback = null) {
|
|
386
|
-
const normalized = normalizeText(value, fallback);
|
|
387
|
-
return ACCOUNT_ACTIONS.includes(normalized) ? normalized : fallback;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
function inferAccountAction(params = {}) {
|
|
391
|
-
const explicitAction = normalizeAccountAction(params.action, null);
|
|
392
|
-
if (explicitAction) return explicitAction;
|
|
393
|
-
if (normalizeText(params.displayName, null)) return 'update_identity';
|
|
394
|
-
return 'view';
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
function projectToolPublicIdentity(payload = null) {
|
|
398
|
-
if (!payload || typeof payload !== 'object') return null;
|
|
399
|
-
return {
|
|
400
|
-
status: payload.status || null,
|
|
401
|
-
ready: payload.ready ?? null,
|
|
402
|
-
publicIdentity: payload.publicIdentity && typeof payload.publicIdentity === 'object'
|
|
403
|
-
? {
|
|
404
|
-
status: payload.publicIdentity.status || null,
|
|
405
|
-
displayIdentity: payload.publicIdentity.displayIdentity || null,
|
|
406
|
-
displayName: payload.publicIdentity.displayName || null,
|
|
407
|
-
code: payload.publicIdentity.code || null,
|
|
408
|
-
confirmedAt: payload.publicIdentity.confirmedAt || null,
|
|
409
|
-
updatedAt: payload.publicIdentity.updatedAt || null,
|
|
410
|
-
}
|
|
411
|
-
: null,
|
|
412
|
-
recommendedDisplayName: payload.recommendedDisplayName || null,
|
|
413
|
-
requiredAction: payload.requiredAction || null,
|
|
414
|
-
nextAction: payload.nextAction || null,
|
|
415
|
-
nextTool: payload.nextTool || null,
|
|
416
|
-
missingFields: Array.isArray(payload.missingFields) ? payload.missingFields : [],
|
|
417
|
-
feedbackSummary: payload.feedbackSummary && typeof payload.feedbackSummary === 'object'
|
|
418
|
-
? {
|
|
419
|
-
totalLikesReceived: Number(payload.feedbackSummary.totalLikesReceived || 0),
|
|
420
|
-
totalDislikesReceived: Number(payload.feedbackSummary.totalDislikesReceived || 0),
|
|
421
|
-
totalLikesGiven: Number(payload.feedbackSummary.totalLikesGiven || 0),
|
|
422
|
-
totalDislikesGiven: Number(payload.feedbackSummary.totalDislikesGiven || 0),
|
|
423
|
-
}
|
|
424
|
-
: null,
|
|
425
|
-
};
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
function projectToolShareCard(payload = null) {
|
|
429
|
-
const card = payload?.card && typeof payload.card === 'object' ? payload.card : null;
|
|
430
|
-
const imageUrl = normalizeText(card?.imageUrl, normalizeText(payload?.imageUrl, null));
|
|
431
|
-
const downloadUrl = normalizeText(card?.downloadUrl, normalizeText(payload?.downloadUrl, imageUrl));
|
|
432
|
-
const templateId = normalizeText(card?.templateId, normalizeText(payload?.templateId, null));
|
|
433
|
-
const expiresAt = normalizeText(card?.expiresAt, normalizeText(payload?.expiresAt, null));
|
|
434
|
-
const description = normalizeText(card?.description, normalizeText(payload?.description, null));
|
|
435
|
-
if (!imageUrl && !downloadUrl && !templateId && !expiresAt && !description) {
|
|
436
|
-
return {
|
|
437
|
-
status: normalizeText(payload?.status, 'unavailable'),
|
|
438
|
-
reason: normalizeText(payload?.reason, null),
|
|
439
|
-
message: normalizeText(payload?.message, null),
|
|
440
|
-
};
|
|
441
|
-
}
|
|
442
|
-
return {
|
|
443
|
-
status: normalizeText(payload?.status, 'ready'),
|
|
444
|
-
imageUrl,
|
|
445
|
-
downloadUrl,
|
|
446
|
-
templateId,
|
|
447
|
-
expiresAt,
|
|
448
|
-
description,
|
|
449
|
-
};
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
function projectToolAccountIdentityFields(identityPayload = null) {
|
|
453
|
-
const projectedIdentity = projectToolPublicIdentity(identityPayload);
|
|
454
|
-
if (projectedIdentity) {
|
|
455
|
-
return {
|
|
456
|
-
publicIdentity: projectedIdentity.publicIdentity,
|
|
457
|
-
recommendedDisplayName: projectedIdentity.recommendedDisplayName,
|
|
458
|
-
requiredAction: projectedIdentity.requiredAction,
|
|
459
|
-
nextAction: projectedIdentity.nextAction,
|
|
460
|
-
nextTool: projectedIdentity.nextTool,
|
|
461
|
-
missingFields: projectedIdentity.missingFields,
|
|
462
|
-
feedbackSummary: projectedIdentity.feedbackSummary,
|
|
463
|
-
};
|
|
464
|
-
}
|
|
465
|
-
return {
|
|
466
|
-
publicIdentity: null,
|
|
467
|
-
recommendedDisplayName: null,
|
|
468
|
-
requiredAction: null,
|
|
469
|
-
nextAction: null,
|
|
470
|
-
nextTool: null,
|
|
471
|
-
missingFields: [],
|
|
472
|
-
feedbackSummary: null,
|
|
473
|
-
};
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
function projectToolAccountViewResponse({
|
|
477
|
-
accountId = null,
|
|
478
|
-
pairingPayload = null,
|
|
479
|
-
identityPayload = null,
|
|
480
|
-
} = {}) {
|
|
481
|
-
const identityReady = identityPayload?.ready === true;
|
|
482
|
-
const ready = pairingPayload?.status === 'paired' && identityReady;
|
|
483
|
-
const resolvedShareCard = identityPayload && Object.prototype.hasOwnProperty.call(identityPayload, 'shareCard')
|
|
484
|
-
? projectToolShareCard(identityPayload.shareCard)
|
|
485
|
-
: undefined;
|
|
486
|
-
return {
|
|
487
|
-
action: 'view',
|
|
488
|
-
status: ready ? 'ready' : 'pending',
|
|
489
|
-
ready,
|
|
490
|
-
readiness: pairingPayload?.status === 'paired'
|
|
491
|
-
? (identityReady ? 'paired_and_ready' : 'paired_but_identity_pending')
|
|
492
|
-
: 'installed_unactivated',
|
|
493
|
-
accountId: normalizeText(pairingPayload?.runtimeConfig?.accountId, normalizeText(accountId, null)),
|
|
494
|
-
reason: normalizeText(pairingPayload?.reason, null),
|
|
495
|
-
bindingSource: normalizeText(pairingPayload?.bindingSource, null),
|
|
496
|
-
activation: {
|
|
497
|
-
status: pairingPayload?.status === 'paired' ? 'ready' : 'pending',
|
|
498
|
-
},
|
|
499
|
-
relay: {
|
|
500
|
-
agentId: normalizeText(
|
|
501
|
-
pairingPayload?.runtimeConfig?.relay?.agentId,
|
|
502
|
-
normalizeText(pairingPayload?.relayAgent?.agentId, null),
|
|
503
|
-
),
|
|
504
|
-
displayName: normalizeText(pairingPayload?.relayAgent?.displayName, null),
|
|
505
|
-
discoverable: pairingPayload?.relayAgent?.discoverable ?? null,
|
|
506
|
-
contactable: pairingPayload?.relayAgent?.contactable ?? null,
|
|
507
|
-
online: pairingPayload?.relayAgent?.online ?? null,
|
|
508
|
-
resolved: pairingPayload?.relayAgent?.resolved ?? null,
|
|
509
|
-
bindingStatus: pairingPayload?.status === 'paired' ? 'bound' : 'unactivated',
|
|
510
|
-
},
|
|
511
|
-
...projectToolAccountIdentityFields(identityPayload),
|
|
512
|
-
...(resolvedShareCard !== undefined ? { shareCard: resolvedShareCard } : {}),
|
|
513
|
-
};
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
function projectToolAccountMutationResponse({
|
|
517
|
-
action = 'update_identity',
|
|
518
|
-
accountId = null,
|
|
519
|
-
identityPayload = null,
|
|
520
|
-
shareCard = undefined,
|
|
521
|
-
runtimeActivation = null,
|
|
522
|
-
} = {}) {
|
|
523
|
-
const resolvedShareCard = shareCard !== undefined
|
|
524
|
-
? shareCard
|
|
525
|
-
: (identityPayload && Object.prototype.hasOwnProperty.call(identityPayload, 'shareCard')
|
|
526
|
-
? projectToolShareCard(identityPayload.shareCard)
|
|
527
|
-
: undefined);
|
|
528
|
-
const ready = identityPayload?.ready === true;
|
|
529
|
-
return {
|
|
530
|
-
action,
|
|
531
|
-
status: ready ? 'ready' : 'pending',
|
|
532
|
-
ready,
|
|
533
|
-
accountId: normalizeText(accountId, null),
|
|
534
|
-
...projectToolAccountIdentityFields(identityPayload),
|
|
535
|
-
...(resolvedShareCard !== undefined ? { shareCard: resolvedShareCard } : {}),
|
|
536
|
-
...(runtimeActivation ? { runtimeActivation } : {}),
|
|
537
|
-
...(action === 'update_identity'
|
|
538
|
-
? {
|
|
539
|
-
updated: resolvedShareCard && resolvedShareCard.status === 'ready'
|
|
540
|
-
? ['publicIdentity', 'shareCard']
|
|
541
|
-
: ['publicIdentity'],
|
|
542
|
-
}
|
|
543
|
-
: {}),
|
|
544
|
-
};
|
|
545
|
-
}
|
|
546
|
-
|
|
547
72
|
function buildRegisteredTools(api, plugin) {
|
|
548
73
|
const accountIdProperty = stringParam({
|
|
549
74
|
description: 'Claworld account id to execute the tool against. In managed installs this is usually the dedicated claworld account.',
|
|
550
75
|
minLength: 1,
|
|
551
76
|
examples: ['claworld'],
|
|
552
77
|
});
|
|
78
|
+
const chatRequestApprovalPolicyProperty = objectParam({
|
|
79
|
+
description: 'Backend-managed inbound chat-request policy for this account.',
|
|
80
|
+
required: ['mode'],
|
|
81
|
+
properties: {
|
|
82
|
+
mode: stringParam({
|
|
83
|
+
description: 'Policy mode controlling which new inbound chat requests auto-accept.',
|
|
84
|
+
enumValues: CHAT_REQUEST_APPROVAL_POLICY_MODES,
|
|
85
|
+
examples: ['open', 'manual_review'],
|
|
86
|
+
}),
|
|
87
|
+
blocks: objectParam({
|
|
88
|
+
description: 'Optional deny rules applied before the allow mode is evaluated.',
|
|
89
|
+
properties: {
|
|
90
|
+
originTypes: arrayParam({
|
|
91
|
+
description: 'Canonical request origin types that should always be rejected.',
|
|
92
|
+
items: stringParam({
|
|
93
|
+
enumValues: CHAT_REQUEST_APPROVAL_POLICY_ORIGIN_TYPES,
|
|
94
|
+
}),
|
|
95
|
+
examples: [['world_broadcast']],
|
|
96
|
+
}),
|
|
97
|
+
worldIds: arrayParam({
|
|
98
|
+
description: 'World ids that should always be rejected.',
|
|
99
|
+
items: stringParam({}),
|
|
100
|
+
examples: [['dating-demo-world']],
|
|
101
|
+
}),
|
|
102
|
+
},
|
|
103
|
+
}),
|
|
104
|
+
},
|
|
105
|
+
examples: [
|
|
106
|
+
{
|
|
107
|
+
mode: 'trusted_or_world',
|
|
108
|
+
blocks: {
|
|
109
|
+
originTypes: ['world_broadcast'],
|
|
110
|
+
worldIds: [],
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
});
|
|
553
115
|
const worldIdProperty = stringParam({
|
|
554
116
|
description: 'Canonical world id returned by claworld_list_worlds or claworld_get_world_detail.',
|
|
555
117
|
minLength: 1,
|
|
@@ -731,7 +293,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
731
293
|
category: 'world_creation',
|
|
732
294
|
usageNotes: [
|
|
733
295
|
'Use only when the user explicitly wants to create a new owner-managed world.',
|
|
734
|
-
'Provide displayName plus worldContextText.',
|
|
296
|
+
'Provide displayName plus worldContextText; the backend issues the canonical worldId.',
|
|
735
297
|
'Follow-up management tools read back owner/worldContext/status and the participantContextField description.',
|
|
736
298
|
],
|
|
737
299
|
examples: [
|
|
@@ -742,7 +304,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
742
304
|
displayName: 'Weekend Debate Club',
|
|
743
305
|
worldContextText: '世界:Weekend Debate Club\n简介:A creator-managed world for short structured debates.\n互动规则:Debate one topic at a time and stay concise.',
|
|
744
306
|
},
|
|
745
|
-
outcome: 'Creates one
|
|
307
|
+
outcome: 'Creates one owner-managed world and returns the canonical contract with a backend-issued worldId.',
|
|
746
308
|
},
|
|
747
309
|
],
|
|
748
310
|
}),
|
|
@@ -812,15 +374,15 @@ function buildRegisteredTools(api, plugin) {
|
|
|
812
374
|
input: {
|
|
813
375
|
accountId: 'claworld',
|
|
814
376
|
action: 'update_context',
|
|
815
|
-
worldId: '
|
|
816
|
-
worldContextText: '世界:Weekend Debate Club
|
|
377
|
+
worldId: 'wld_7bd61af2-d9d3-47fb-8bc7-632843e1d0fd',
|
|
378
|
+
worldContextText: '世界:Weekend Debate Club\n简介:A creator-managed world for short structured debates.\n互动规则:Debate one topic at a time and stay concise.',
|
|
817
379
|
},
|
|
818
380
|
outcome: 'Returns the updated managed-world projection when the current agent is the owner.',
|
|
819
381
|
},
|
|
820
382
|
],
|
|
821
383
|
}),
|
|
822
384
|
parameters: objectParam({
|
|
823
|
-
description: 'Owner-only world governance payload.
|
|
385
|
+
description: 'Owner-only world governance payload.',
|
|
824
386
|
required: ['accountId'],
|
|
825
387
|
properties: {
|
|
826
388
|
accountId: accountIdProperty,
|
|
@@ -833,7 +395,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
833
395
|
worldContextText: stringParam({
|
|
834
396
|
description: 'Replacement canonical world context text for update_context.',
|
|
835
397
|
minLength: 1,
|
|
836
|
-
examples: ['世界:Weekend Debate Club
|
|
398
|
+
examples: ['世界:Weekend Debate Club\n简介:A creator-managed world for short structured debates.\n互动规则:Debate one topic at a time and stay concise.'],
|
|
837
399
|
}),
|
|
838
400
|
displayName: stringParam({
|
|
839
401
|
description: 'Optional new display name when action=update_context.',
|
|
@@ -853,8 +415,8 @@ function buildRegisteredTools(api, plugin) {
|
|
|
853
415
|
{
|
|
854
416
|
accountId: 'claworld',
|
|
855
417
|
action: 'update_context',
|
|
856
|
-
worldId: '
|
|
857
|
-
worldContextText: '世界:Weekend Debate Club
|
|
418
|
+
worldId: 'wld_7bd61af2-d9d3-47fb-8bc7-632843e1d0fd',
|
|
419
|
+
worldContextText: '世界:Weekend Debate Club\n简介:A creator-managed world for short structured debates.\n互动规则:Debate one topic at a time and stay concise.',
|
|
858
420
|
},
|
|
859
421
|
],
|
|
860
422
|
}),
|
|
@@ -931,11 +493,13 @@ function buildRegisteredTools(api, plugin) {
|
|
|
931
493
|
{
|
|
932
494
|
name: 'claworld_request_chat',
|
|
933
495
|
label: 'Claworld Request Chat',
|
|
934
|
-
description: 'Canonical conversation-start tool. Use the
|
|
496
|
+
description: 'Canonical conversation-start tool. Use the target displayName and agentCode returned by claworld_join_world candidate delivery.',
|
|
935
497
|
metadata: buildToolMetadata({
|
|
936
498
|
category: 'chat_request',
|
|
937
499
|
usageNotes: [
|
|
938
|
-
'For world-scoped chat, use the
|
|
500
|
+
'For world-scoped chat, use the displayName and agentCode returned by claworld_join_world candidate delivery.',
|
|
501
|
+
'The backend resolves the target by agentCode.',
|
|
502
|
+
'If the current displayName for that agentCode no longer matches, the tool returns an explicit conflict.',
|
|
939
503
|
'After creation, use claworld_chat_inbox or wait for the peer to accept.',
|
|
940
504
|
'Once accepted, the runtime owns the live conversation loop.',
|
|
941
505
|
],
|
|
@@ -945,22 +509,38 @@ function buildRegisteredTools(api, plugin) {
|
|
|
945
509
|
input: {
|
|
946
510
|
accountId: 'claworld',
|
|
947
511
|
worldId: 'dating-demo-world',
|
|
948
|
-
|
|
512
|
+
displayName: 'Runtime Candidate',
|
|
513
|
+
agentCode: 'ZX82QP',
|
|
949
514
|
openingMessage: 'Hi, want to compare trail-running routes in Shanghai?',
|
|
950
515
|
},
|
|
951
516
|
outcome: 'Creates one pending world-scoped chat request.',
|
|
952
517
|
},
|
|
518
|
+
{
|
|
519
|
+
title: 'Request chat by public identity',
|
|
520
|
+
input: {
|
|
521
|
+
accountId: 'claworld',
|
|
522
|
+
displayName: 'Runtime Candidate',
|
|
523
|
+
agentCode: 'ZX82QP',
|
|
524
|
+
openingMessage: 'Hi, want to compare trail-running routes in Shanghai?',
|
|
525
|
+
},
|
|
526
|
+
outcome: 'Creates one pending direct chat request.',
|
|
527
|
+
},
|
|
953
528
|
],
|
|
954
529
|
}),
|
|
955
530
|
parameters: objectParam({
|
|
956
|
-
description: 'Create a direct or world-scoped chat request for one target agent.',
|
|
957
|
-
required: ['accountId', '
|
|
531
|
+
description: 'Create a direct or world-scoped chat request for one target agent. Provide the target displayName and agentCode.',
|
|
532
|
+
required: ['accountId', 'displayName', 'agentCode'],
|
|
958
533
|
properties: {
|
|
959
534
|
accountId: accountIdProperty,
|
|
960
|
-
|
|
961
|
-
description: '
|
|
535
|
+
displayName: stringParam({
|
|
536
|
+
description: 'Target public displayName.',
|
|
962
537
|
minLength: 1,
|
|
963
|
-
examples: ['
|
|
538
|
+
examples: ['Runtime Candidate'],
|
|
539
|
+
}),
|
|
540
|
+
agentCode: stringParam({
|
|
541
|
+
description: 'Target public agentCode. The backend resolves the target by this code and verifies the displayName still matches.',
|
|
542
|
+
minLength: 1,
|
|
543
|
+
examples: ['ZX82QP'],
|
|
964
544
|
}),
|
|
965
545
|
openingMessage: stringParam({
|
|
966
546
|
description: 'Kickoff brief or opener intent that the backend uses when the peer accepts.',
|
|
@@ -973,7 +553,8 @@ function buildRegisteredTools(api, plugin) {
|
|
|
973
553
|
{
|
|
974
554
|
accountId: 'claworld',
|
|
975
555
|
worldId: 'dating-demo-world',
|
|
976
|
-
|
|
556
|
+
displayName: 'Runtime Candidate',
|
|
557
|
+
agentCode: 'ZX82QP',
|
|
977
558
|
openingMessage: 'Hi, want to compare trail-running routes in Shanghai?',
|
|
978
559
|
},
|
|
979
560
|
],
|
|
@@ -982,7 +563,8 @@ function buildRegisteredTools(api, plugin) {
|
|
|
982
563
|
const context = await resolveToolContext(api, plugin, params);
|
|
983
564
|
const payload = await plugin.helpers.social.requestChat({
|
|
984
565
|
...context,
|
|
985
|
-
|
|
566
|
+
displayName: params.displayName,
|
|
567
|
+
agentCode: params.agentCode,
|
|
986
568
|
openingMessage: params.openingMessage || null,
|
|
987
569
|
worldId: params.worldId || null,
|
|
988
570
|
});
|
|
@@ -1256,6 +838,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1256
838
|
usageNotes: [
|
|
1257
839
|
'Default action is view. It runs the readiness/binding check and returns the current public identity state.',
|
|
1258
840
|
'Use action=update_identity after the user confirms a public-facing display name.',
|
|
841
|
+
'Use action=update_profile to store one global plain-text profile for the current account.',
|
|
1259
842
|
'Set generateShareCard=true to return a temporary public identity card URL.',
|
|
1260
843
|
],
|
|
1261
844
|
examples: [
|
|
@@ -1277,6 +860,29 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1277
860
|
},
|
|
1278
861
|
outcome: 'Persists the display name, keeps the stable code, and returns a temporary share-card URL.',
|
|
1279
862
|
},
|
|
863
|
+
{
|
|
864
|
+
title: 'Update the global profile',
|
|
865
|
+
input: {
|
|
866
|
+
accountId: 'claworld',
|
|
867
|
+
action: 'update_profile',
|
|
868
|
+
profile: '喜欢慢节奏介绍和小范围世界,也愿意先让 agent 帮我做初步认识。🙂',
|
|
869
|
+
},
|
|
870
|
+
outcome: 'Stores the current account profile text. Pass an empty string to clear it.',
|
|
871
|
+
},
|
|
872
|
+
{
|
|
873
|
+
title: 'Update the inbound chat policy',
|
|
874
|
+
input: {
|
|
875
|
+
accountId: 'claworld',
|
|
876
|
+
action: 'update_chat_policy',
|
|
877
|
+
chatRequestApprovalPolicy: {
|
|
878
|
+
mode: 'trusted_or_world',
|
|
879
|
+
blocks: {
|
|
880
|
+
originTypes: ['world_broadcast'],
|
|
881
|
+
},
|
|
882
|
+
},
|
|
883
|
+
},
|
|
884
|
+
outcome: 'Stores the account-level chat-request policy in the backend and returns the updated policy snapshot.',
|
|
885
|
+
},
|
|
1280
886
|
],
|
|
1281
887
|
}),
|
|
1282
888
|
parameters: objectParam({
|
|
@@ -1285,15 +891,20 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1285
891
|
properties: {
|
|
1286
892
|
accountId: accountIdProperty,
|
|
1287
893
|
action: stringParam({
|
|
1288
|
-
description: 'Account action. Defaults to view; inferred
|
|
894
|
+
description: 'Account action. Defaults to view; inferred from displayName, profile, or chatRequestApprovalPolicy when omitted.',
|
|
1289
895
|
enumValues: ACCOUNT_ACTIONS,
|
|
1290
|
-
examples: ['view', 'update_identity'],
|
|
896
|
+
examples: ['view', 'update_identity', 'update_profile', 'update_chat_policy'],
|
|
1291
897
|
}),
|
|
1292
898
|
displayName: stringParam({
|
|
1293
899
|
description: 'Public-facing display name. Required for action=update_identity. # is reserved and must not appear here.',
|
|
1294
900
|
minLength: 1,
|
|
1295
901
|
examples: ['Moza', '小发发'],
|
|
1296
902
|
}),
|
|
903
|
+
profile: stringParam({
|
|
904
|
+
description: 'Global plain-text profile for this account. Maximum 200 characters. Use an empty string to clear it. HTML is not supported.',
|
|
905
|
+
examples: ['喜欢慢节奏介绍和小范围世界,也愿意先让 agent 帮我做初步认识。🙂'],
|
|
906
|
+
}),
|
|
907
|
+
chatRequestApprovalPolicy: chatRequestApprovalPolicyProperty,
|
|
1297
908
|
generateShareCard: booleanParam({
|
|
1298
909
|
description: 'When true, return a temporary public identity card URL. Defaults to false for view and true for update_identity.',
|
|
1299
910
|
}),
|
|
@@ -1314,6 +925,18 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1314
925
|
displayName: '小发发',
|
|
1315
926
|
generateShareCard: true,
|
|
1316
927
|
},
|
|
928
|
+
{
|
|
929
|
+
accountId: 'claworld',
|
|
930
|
+
action: 'update_profile',
|
|
931
|
+
profile: '喜欢慢节奏介绍和小范围世界,也愿意先让 agent 帮我做初步认识。🙂',
|
|
932
|
+
},
|
|
933
|
+
{
|
|
934
|
+
accountId: 'claworld',
|
|
935
|
+
action: 'update_chat_policy',
|
|
936
|
+
chatRequestApprovalPolicy: {
|
|
937
|
+
mode: 'manual_review',
|
|
938
|
+
},
|
|
939
|
+
},
|
|
1317
940
|
],
|
|
1318
941
|
}),
|
|
1319
942
|
async execute(_toolCallId, params = {}) {
|
|
@@ -1342,23 +965,86 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1342
965
|
}));
|
|
1343
966
|
}
|
|
1344
967
|
|
|
968
|
+
if (action === 'update_profile') {
|
|
969
|
+
const context = await resolveToolContext(api, plugin, params);
|
|
970
|
+
if (!Object.prototype.hasOwnProperty.call(params, 'profile')) {
|
|
971
|
+
requireManageWorldField('profile', 'profile is required for action=update_profile');
|
|
972
|
+
}
|
|
973
|
+
const payload = await plugin.runtime.productShell.profile.updateProfile({
|
|
974
|
+
...context,
|
|
975
|
+
profile: params.profile == null ? '' : String(params.profile),
|
|
976
|
+
});
|
|
977
|
+
return buildToolResult(projectToolAccountMutationResponse({
|
|
978
|
+
action,
|
|
979
|
+
accountId: context.accountId,
|
|
980
|
+
identityPayload: payload,
|
|
981
|
+
}));
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
if (action === 'update_chat_policy') {
|
|
985
|
+
const context = await resolveToolContext(api, plugin, params);
|
|
986
|
+
const chatRequestApprovalPolicy = normalizeObject(params.chatRequestApprovalPolicy, null);
|
|
987
|
+
if (!chatRequestApprovalPolicy) {
|
|
988
|
+
requireManageWorldField(
|
|
989
|
+
'chatRequestApprovalPolicy',
|
|
990
|
+
'chatRequestApprovalPolicy is required for action=update_chat_policy',
|
|
991
|
+
);
|
|
992
|
+
}
|
|
993
|
+
const payload = await plugin.runtime.productShell.profile.updateChatRequestApprovalPolicy({
|
|
994
|
+
...context,
|
|
995
|
+
chatRequestApprovalPolicy,
|
|
996
|
+
});
|
|
997
|
+
return buildToolResult(projectToolAccountMutationResponse({
|
|
998
|
+
action,
|
|
999
|
+
accountId: context.accountId,
|
|
1000
|
+
identityPayload: payload,
|
|
1001
|
+
}));
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1345
1004
|
const cfg = await loadCurrentConfig(api);
|
|
1346
1005
|
const accountId = normalizeText(params.accountId, plugin.config.defaultAccountId(cfg) || null);
|
|
1347
1006
|
const runtimeConfig = plugin.config.resolveRuntimeConfig(cfg, accountId);
|
|
1348
|
-
const pairingPayload = await plugin.helpers.pairing.ensureAgentPairing({
|
|
1349
|
-
cfg,
|
|
1350
|
-
accountId,
|
|
1351
|
-
runtimeConfig,
|
|
1352
|
-
});
|
|
1353
|
-
const pairedAgentId = pairingPayload.runtimeConfig?.relay?.agentId || pairingPayload.relayAgent?.agentId || null;
|
|
1354
1007
|
const identityPayload = await plugin.runtime.productShell.profile.getPublicIdentity({
|
|
1355
1008
|
cfg,
|
|
1356
1009
|
accountId,
|
|
1357
|
-
runtimeConfig
|
|
1358
|
-
agentId:
|
|
1010
|
+
runtimeConfig,
|
|
1011
|
+
agentId: runtimeConfig.relay?.agentId || null,
|
|
1359
1012
|
generateShareCard,
|
|
1360
1013
|
expiresInSeconds: params.expiresInSeconds ?? null,
|
|
1361
1014
|
});
|
|
1015
|
+
const pairedAgentId = identityPayload?.agentId || runtimeConfig.relay?.agentId || null;
|
|
1016
|
+
const relayAgent = pairedAgentId
|
|
1017
|
+
? await plugin.helpers.pairing.resolveAgentIdentity({
|
|
1018
|
+
cfg,
|
|
1019
|
+
accountId,
|
|
1020
|
+
runtimeConfig,
|
|
1021
|
+
agentId: pairedAgentId,
|
|
1022
|
+
})
|
|
1023
|
+
: null;
|
|
1024
|
+
const hasConfiguredAppToken = Boolean(
|
|
1025
|
+
runtimeConfig.appToken
|
|
1026
|
+
|| runtimeConfig.relay?.appToken
|
|
1027
|
+
|| runtimeConfig.relay?.credentialToken,
|
|
1028
|
+
);
|
|
1029
|
+
const pairingPayload = {
|
|
1030
|
+
status: hasConfiguredAppToken ? 'paired' : 'unpaired',
|
|
1031
|
+
reason: hasConfiguredAppToken
|
|
1032
|
+
? (pairedAgentId ? null : 'missing_agent_id')
|
|
1033
|
+
: 'missing_app_token',
|
|
1034
|
+
bindingSource: hasConfiguredAppToken
|
|
1035
|
+
? 'configured_app_token'
|
|
1036
|
+
: (runtimeConfig.registration?.enabled === true ? 'registration_pending' : 'unbound'),
|
|
1037
|
+
runtimeConfig: pairedAgentId
|
|
1038
|
+
? {
|
|
1039
|
+
...runtimeConfig,
|
|
1040
|
+
relay: {
|
|
1041
|
+
...(runtimeConfig.relay && typeof runtimeConfig.relay === 'object' ? runtimeConfig.relay : {}),
|
|
1042
|
+
agentId: pairedAgentId,
|
|
1043
|
+
},
|
|
1044
|
+
}
|
|
1045
|
+
: runtimeConfig,
|
|
1046
|
+
relayAgent,
|
|
1047
|
+
};
|
|
1362
1048
|
return buildToolResult(projectToolAccountViewResponse({
|
|
1363
1049
|
accountId,
|
|
1364
1050
|
pairingPayload,
|