@xfxstudio/claworld 0.2.9 → 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 +5 -1
- package/skills/claworld-join-and-chat/SKILL.md +21 -1
- package/skills/claworld-manage-worlds/SKILL.md +81 -10
- package/src/lib/agent-profile.js +8 -3
- package/src/lib/chat-request.js +0 -1
- package/src/lib/policy.js +2 -6
- package/src/lib/public-identity.js +175 -0
- package/src/lib/relay/kickoff-text.js +1 -0
- 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 +270 -255
- 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 +109 -10
- package/src/openclaw/plugin/relay-client.js +233 -17
- 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 +26 -3
- package/src/openclaw/runtime/tool-inventory.js +7 -0
- 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-service.js +22 -7
- 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
|
@@ -45,12 +45,14 @@ import {
|
|
|
45
45
|
resolveWorldSelection,
|
|
46
46
|
resolveWorldSelectionFlow,
|
|
47
47
|
} from '../runtime/product-shell-helper.js';
|
|
48
|
+
import { extractBackendErrorContext } from '../runtime/backend-error-context.js';
|
|
48
49
|
import { getClaworldRuntime } from './runtime.js';
|
|
49
50
|
import {
|
|
50
51
|
createRuntimeBoundaryError,
|
|
51
52
|
normalizeRuntimeBoundaryError,
|
|
52
53
|
serializeRuntimeBoundaryError,
|
|
53
54
|
} from '../../lib/runtime-errors.js';
|
|
55
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
54
56
|
|
|
55
57
|
function normalizeRelayHttpBaseUrl(serverUrl) {
|
|
56
58
|
const parsed = new URL(serverUrl);
|
|
@@ -67,108 +69,16 @@ function normalizePluginOptionalText(value) {
|
|
|
67
69
|
return normalized || null;
|
|
68
70
|
}
|
|
69
71
|
|
|
70
|
-
function
|
|
71
|
-
|
|
72
|
-
const atIndex = defaultToAddress.indexOf('@');
|
|
73
|
-
if (atIndex > 0 && atIndex < defaultToAddress.length - 1) {
|
|
74
|
-
return defaultToAddress.slice(atIndex + 1).trim().toLowerCase();
|
|
75
|
-
}
|
|
76
|
-
return 'relay.local';
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const RELAY_LOCAL_AGENT_CODE_PATTERN = /^[A-Za-z0-9._:+~-]+$/;
|
|
80
|
-
const RELAY_CANONICAL_AGENT_CODE_PATTERN = /^[A-Za-z0-9._:+~-]+@[A-Za-z0-9._:+~-]+$/;
|
|
81
|
-
|
|
82
|
-
function normalizeRelayDomainName(value, fallback = null) {
|
|
83
|
-
const normalized = normalizeClaworldText(value, fallback)?.toLowerCase() || null;
|
|
84
|
-
if (!normalized) return fallback;
|
|
85
|
-
if (!/^[a-z0-9._:+~-]+$/.test(normalized)) return fallback;
|
|
86
|
-
return normalized;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function normalizeRelayLocalAgentCode(value, fallback = null) {
|
|
90
|
-
const normalized = normalizeClaworldText(value, fallback)?.toLowerCase() || null;
|
|
91
|
-
if (!normalized) return fallback;
|
|
92
|
-
if (!RELAY_LOCAL_AGENT_CODE_PATTERN.test(normalized)) return fallback;
|
|
93
|
-
return normalized;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function parseCanonicalRelayAgentCode(value) {
|
|
97
|
-
const normalized = normalizeClaworldText(value, null)?.toLowerCase() || null;
|
|
98
|
-
if (!normalized || !RELAY_CANONICAL_AGENT_CODE_PATTERN.test(normalized)) return null;
|
|
99
|
-
const atIndex = normalized.indexOf('@');
|
|
100
|
-
if (atIndex <= 0 || atIndex >= normalized.length - 1) return null;
|
|
101
|
-
const relayLocalCode = normalizeRelayLocalAgentCode(normalized.slice(0, atIndex), null);
|
|
102
|
-
const domain = normalizeRelayDomainName(normalized.slice(atIndex + 1), null);
|
|
103
|
-
if (!relayLocalCode || !domain) return null;
|
|
104
|
-
return {
|
|
105
|
-
agentCode: `${relayLocalCode}@${domain}`,
|
|
106
|
-
relayLocalCode,
|
|
107
|
-
domain,
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function buildCanonicalRelayAgentCode(relayLocalCode, runtimeConfig = {}, domainOverride = null) {
|
|
112
|
-
const normalizedRelayLocalCode = normalizeRelayLocalAgentCode(relayLocalCode, null);
|
|
113
|
-
const domain = normalizeRelayDomainName(domainOverride, null)
|
|
114
|
-
|| normalizeRelayDomainName(inferRelayDomain(runtimeConfig), null);
|
|
115
|
-
if (!normalizedRelayLocalCode || !domain) return null;
|
|
116
|
-
return `${normalizedRelayLocalCode}@${domain}`;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function normalizeCanonicalRelayAgentCode(value, runtimeConfig = {}) {
|
|
120
|
-
const parsed = parseCanonicalRelayAgentCode(value);
|
|
121
|
-
if (parsed) return parsed.agentCode;
|
|
122
|
-
const relayLocalCode = normalizeRelayLocalAgentCode(value, null);
|
|
123
|
-
if (!relayLocalCode) return null;
|
|
124
|
-
return buildCanonicalRelayAgentCode(relayLocalCode, runtimeConfig);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function normalizeRelayIdentityInput({ runtimeConfig = {}, agentId = null, agentCode = null, address = null } = {}) {
|
|
128
|
-
const normalizedAgentId = normalizeClaworldText(agentId, null);
|
|
129
|
-
const normalizedAddress = normalizeClaworldText(resolveRelayAddress(address || agentCode || '', runtimeConfig), null)?.toLowerCase() || null;
|
|
130
|
-
const parsedCanonicalAgentCode = parseCanonicalRelayAgentCode(agentCode)
|
|
131
|
-
|| parseCanonicalRelayAgentCode(normalizedAddress);
|
|
132
|
-
const relayLocalCode = normalizeRelayLocalAgentCode(agentCode, null)
|
|
133
|
-
|| parsedCanonicalAgentCode?.relayLocalCode
|
|
134
|
-
|| null;
|
|
135
|
-
const domain = parsedCanonicalAgentCode?.domain
|
|
136
|
-
|| normalizeRelayDomainName(normalizedAddress?.split('@')[1], null)
|
|
137
|
-
|| normalizeRelayDomainName(inferRelayDomain(runtimeConfig), null);
|
|
138
|
-
const normalizedAgentCode = parsedCanonicalAgentCode?.agentCode
|
|
139
|
-
|| (relayLocalCode ? buildCanonicalRelayAgentCode(relayLocalCode, runtimeConfig, domain) : null)
|
|
140
|
-
|| null;
|
|
141
|
-
|
|
142
|
-
return {
|
|
143
|
-
agentId: normalizedAgentId,
|
|
144
|
-
agentCode: normalizedAgentCode,
|
|
145
|
-
relayLocalCode,
|
|
146
|
-
address: normalizedAddress || normalizedAgentCode || null,
|
|
147
|
-
domain,
|
|
148
|
-
};
|
|
72
|
+
function resolveClientMessageId(value = null) {
|
|
73
|
+
return normalizePluginOptionalText(value) || `cmsg_${uuidv4()}`;
|
|
149
74
|
}
|
|
150
75
|
|
|
151
|
-
function buildRelayAgentSummary(item = {}
|
|
76
|
+
function buildRelayAgentSummary(item = {}) {
|
|
152
77
|
const normalizedAgentId = normalizeClaworldText(item?.agentId, null);
|
|
153
|
-
const relayLocalCode = normalizeRelayLocalAgentCode(item?.agentCode, null);
|
|
154
|
-
const address = normalizeClaworldText(item?.address, null)?.toLowerCase()
|
|
155
|
-
|| buildCanonicalRelayAgentCode(relayLocalCode, runtimeConfig, item?.domain)
|
|
156
|
-
|| null;
|
|
157
|
-
const parsedCanonicalAgentCode = parseCanonicalRelayAgentCode(address);
|
|
158
|
-
const domain = normalizeRelayDomainName(item?.domain, null)
|
|
159
|
-
|| parsedCanonicalAgentCode?.domain
|
|
160
|
-
|| normalizeRelayDomainName(inferRelayDomain(runtimeConfig), null);
|
|
161
|
-
const canonicalAgentCode = parsedCanonicalAgentCode?.agentCode
|
|
162
|
-
|| buildCanonicalRelayAgentCode(relayLocalCode, runtimeConfig, domain)
|
|
163
|
-
|| null;
|
|
164
|
-
|
|
165
78
|
return {
|
|
166
79
|
agentId: normalizedAgentId,
|
|
167
|
-
agentCode: canonicalAgentCode,
|
|
168
|
-
relayLocalCode: relayLocalCode || parsedCanonicalAgentCode?.relayLocalCode || null,
|
|
169
|
-
domain,
|
|
170
|
-
address: address || canonicalAgentCode || null,
|
|
171
80
|
displayName: normalizeClaworldText(item?.displayName, null),
|
|
81
|
+
publicIdentity: item?.publicIdentity && typeof item.publicIdentity === 'object' ? item.publicIdentity : null,
|
|
172
82
|
discoverable: typeof item?.discoverable === 'boolean' ? item.discoverable : null,
|
|
173
83
|
contactable: typeof item?.contactable === 'boolean' ? item.contactable : null,
|
|
174
84
|
online: typeof item?.online === 'boolean' ? item.online : null,
|
|
@@ -179,19 +89,10 @@ function normalizeClaworldTarget(raw) {
|
|
|
179
89
|
if (typeof raw !== 'string') return undefined;
|
|
180
90
|
let value = raw.trim();
|
|
181
91
|
if (!value) return undefined;
|
|
182
|
-
value = value.replace(/^claworld:/i, '').replace(/^user:/i, '').
|
|
92
|
+
value = value.replace(/^claworld:/i, '').replace(/^user:/i, '').trim();
|
|
183
93
|
return value || undefined;
|
|
184
94
|
}
|
|
185
95
|
|
|
186
|
-
function resolveRelayAddress(to, runtimeConfig = {}) {
|
|
187
|
-
const normalized = normalizeClaworldTarget(typeof to === 'string' ? to : '');
|
|
188
|
-
const fallback = normalizeClaworldTarget(runtimeConfig.relay?.defaultToAddress || '');
|
|
189
|
-
const candidate = normalized || fallback;
|
|
190
|
-
if (!candidate) return '';
|
|
191
|
-
if (candidate.includes('@')) return candidate.toLowerCase();
|
|
192
|
-
return `${candidate.toLowerCase()}@${inferRelayDomain(runtimeConfig)}`;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
96
|
function normalizeClaworldText(value, fallback = null) {
|
|
196
97
|
if (value == null) return fallback;
|
|
197
98
|
const normalized = String(value).trim();
|
|
@@ -215,6 +116,45 @@ function shouldAuthorizeBridgedCommand({ runtimeConfig = {}, incomingText }) {
|
|
|
215
116
|
return typeof incomingText === 'string' && incomingText.trim().startsWith('/');
|
|
216
117
|
}
|
|
217
118
|
|
|
119
|
+
function normalizeUntrustedContextLines(value) {
|
|
120
|
+
if (Array.isArray(value)) {
|
|
121
|
+
return value
|
|
122
|
+
.map((entry) => resolveNormalizedText(entry, null))
|
|
123
|
+
.filter(Boolean);
|
|
124
|
+
}
|
|
125
|
+
const singleLine = resolveNormalizedText(value, null);
|
|
126
|
+
return singleLine ? [singleLine] : [];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function mergeUntrustedContextLines(...groups) {
|
|
130
|
+
const merged = [];
|
|
131
|
+
const seen = new Set();
|
|
132
|
+
for (const group of groups) {
|
|
133
|
+
for (const line of normalizeUntrustedContextLines(group)) {
|
|
134
|
+
if (seen.has(line)) continue;
|
|
135
|
+
seen.add(line);
|
|
136
|
+
merged.push(line);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return merged;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function parseBridgeTimestampMs(value) {
|
|
143
|
+
if (typeof value === 'number' && Number.isFinite(value)) return value;
|
|
144
|
+
if (typeof value !== 'string') return null;
|
|
145
|
+
const normalized = value.trim();
|
|
146
|
+
if (!normalized) return null;
|
|
147
|
+
const parsed = Date.parse(normalized);
|
|
148
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function resolveBridgeDeliveryTimestampMs({ delivery = {}, metadata = {} } = {}) {
|
|
152
|
+
return parseBridgeTimestampMs(delivery?.createdAt)
|
|
153
|
+
|| parseBridgeTimestampMs(delivery?.turnCreatedAt)
|
|
154
|
+
|| parseBridgeTimestampMs(metadata?.createdAt)
|
|
155
|
+
|| Date.now();
|
|
156
|
+
}
|
|
157
|
+
|
|
218
158
|
const CLAWORLD_RELAY_OPERATIONAL_NOTICE_PATTERNS = [
|
|
219
159
|
/^🧭\s*New session:\s+\S+/i,
|
|
220
160
|
/^🧹\s*Auto-compaction complete(?:\s*\(count \d+\))?\.$/i,
|
|
@@ -355,10 +295,11 @@ function buildClaworldDirectoryEntries(config = {}, accountId = null) {
|
|
|
355
295
|
const account = inspectClaworldChannelAccount(config, id);
|
|
356
296
|
if (!account?.enabled || !account?.configured) continue;
|
|
357
297
|
const normalizedId = String(account.accountId || id || '').trim();
|
|
358
|
-
|
|
298
|
+
const boundAgentId = normalizeClaworldText(account.relay?.agentId, null);
|
|
299
|
+
if (!normalizedId || !boundAgentId) continue;
|
|
359
300
|
if (currentAccountId && normalizedId === currentAccountId) continue;
|
|
360
301
|
entries.push({
|
|
361
|
-
id:
|
|
302
|
+
id: boundAgentId,
|
|
362
303
|
name: normalizedId,
|
|
363
304
|
handle: normalizedId,
|
|
364
305
|
rank: 100,
|
|
@@ -366,11 +307,10 @@ function buildClaworldDirectoryEntries(config = {}, accountId = null) {
|
|
|
366
307
|
}
|
|
367
308
|
|
|
368
309
|
const current = inspectClaworldChannelAccount(config, currentAccountId || null);
|
|
369
|
-
const
|
|
370
|
-
if (
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
entries.push({ id: defaultTarget, name: localPart, handle: localPart, rank: 50 });
|
|
310
|
+
const defaultTargetAgentId = normalizeClaworldText(current?.relay?.defaultTargetAgentId, null);
|
|
311
|
+
if (defaultTargetAgentId) {
|
|
312
|
+
if (!entries.some((entry) => entry.id === defaultTargetAgentId)) {
|
|
313
|
+
entries.push({ id: defaultTargetAgentId, name: defaultTargetAgentId, handle: defaultTargetAgentId, rank: 50 });
|
|
374
314
|
}
|
|
375
315
|
}
|
|
376
316
|
|
|
@@ -381,8 +321,8 @@ async function deliverRelayMessage({ runtimeConfig, to, text, fetchImpl, logger,
|
|
|
381
321
|
const fromAgentId = runtimeConfig.relay?.agentId;
|
|
382
322
|
if (!fromAgentId) throw new Error('claworld relay.agentId is required for outbound send');
|
|
383
323
|
|
|
384
|
-
const
|
|
385
|
-
if (!
|
|
324
|
+
const targetAgentId = normalizeClaworldText(to, null);
|
|
325
|
+
if (!targetAgentId) throw new Error('claworld outbound targetAgentId is required');
|
|
386
326
|
|
|
387
327
|
const normalizedText = normalizeClaworldText(text, null);
|
|
388
328
|
const payload = messagePayload && typeof messagePayload === 'object'
|
|
@@ -397,6 +337,9 @@ async function deliverRelayMessage({ runtimeConfig, to, text, fetchImpl, logger,
|
|
|
397
337
|
}
|
|
398
338
|
payload.source = normalizeClaworldText(payload.source, 'openclaw-claworld');
|
|
399
339
|
payload.accountId = normalizeClaworldText(payload.accountId, runtimeConfig.accountId);
|
|
340
|
+
const clientMessageId = resolveClientMessageId(
|
|
341
|
+
outboundContext.clientMessageId || outboundContext.metadata?.clientMessageId || null
|
|
342
|
+
);
|
|
400
343
|
|
|
401
344
|
const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
|
|
402
345
|
const result = await fetchJson(fetchImpl, `${baseUrl}/v1/messages`, {
|
|
@@ -408,7 +351,8 @@ async function deliverRelayMessage({ runtimeConfig, to, text, fetchImpl, logger,
|
|
|
408
351
|
},
|
|
409
352
|
body: JSON.stringify({
|
|
410
353
|
fromAgentId,
|
|
411
|
-
|
|
354
|
+
targetAgentId,
|
|
355
|
+
clientMessageId,
|
|
412
356
|
payload,
|
|
413
357
|
conversation: {
|
|
414
358
|
conversationKey: outboundContext.conversationKey || outboundContext.metadata?.conversationKey || null,
|
|
@@ -433,7 +377,7 @@ async function deliverRelayMessage({ runtimeConfig, to, text, fetchImpl, logger,
|
|
|
433
377
|
context: {
|
|
434
378
|
accountId: runtimeConfig.accountId || null,
|
|
435
379
|
fromAgentId,
|
|
436
|
-
|
|
380
|
+
targetAgentId,
|
|
437
381
|
status: result.status,
|
|
438
382
|
},
|
|
439
383
|
});
|
|
@@ -442,13 +386,14 @@ async function deliverRelayMessage({ runtimeConfig, to, text, fetchImpl, logger,
|
|
|
442
386
|
return {
|
|
443
387
|
channel: 'claworld',
|
|
444
388
|
messageId: result.body?.turn?.turnId || `turn_${Date.now()}`,
|
|
445
|
-
chatId:
|
|
389
|
+
chatId: targetAgentId,
|
|
446
390
|
timestamp: Date.now(),
|
|
447
391
|
meta: {
|
|
392
|
+
clientMessageId,
|
|
448
393
|
sessionKey: result.body?.delivery?.sessionKey || outboundContext.sessionKey || outboundContext.SessionKey || null,
|
|
449
394
|
turnId: result.body?.turn?.turnId || null,
|
|
450
395
|
conversationKey: result.body?.conversationKey || null,
|
|
451
|
-
|
|
396
|
+
targetAgentId,
|
|
452
397
|
},
|
|
453
398
|
};
|
|
454
399
|
}
|
|
@@ -481,8 +426,7 @@ function createRelayRouteError({
|
|
|
481
426
|
context: {
|
|
482
427
|
accountId: runtimeConfig.accountId || null,
|
|
483
428
|
httpStatus: result?.status || null,
|
|
484
|
-
|
|
485
|
-
backendMessage: result?.body?.message || null,
|
|
429
|
+
...extractBackendErrorContext(result?.body),
|
|
486
430
|
...context,
|
|
487
431
|
},
|
|
488
432
|
});
|
|
@@ -491,7 +435,7 @@ function createRelayRouteError({
|
|
|
491
435
|
async function createFriendRequest({
|
|
492
436
|
runtimeConfig,
|
|
493
437
|
fromAgentId,
|
|
494
|
-
|
|
438
|
+
targetAgentId,
|
|
495
439
|
message = null,
|
|
496
440
|
metadata = {},
|
|
497
441
|
fetchImpl,
|
|
@@ -506,7 +450,7 @@ async function createFriendRequest({
|
|
|
506
450
|
},
|
|
507
451
|
body: JSON.stringify({
|
|
508
452
|
fromAgentId,
|
|
509
|
-
|
|
453
|
+
targetAgentId,
|
|
510
454
|
message: normalizeClaworldText(message, null),
|
|
511
455
|
metadata: metadata && typeof metadata === 'object' && !Array.isArray(metadata) ? metadata : {},
|
|
512
456
|
}),
|
|
@@ -517,7 +461,7 @@ async function createFriendRequest({
|
|
|
517
461
|
runtimeConfig,
|
|
518
462
|
code: 'friend_request_failed',
|
|
519
463
|
publicMessage: 'failed to create friend request',
|
|
520
|
-
context: { fromAgentId,
|
|
464
|
+
context: { fromAgentId, targetAgentId },
|
|
521
465
|
});
|
|
522
466
|
}
|
|
523
467
|
return result.body || {};
|
|
@@ -833,16 +777,6 @@ function isNonRecoverableBootstrapHoldError(error) {
|
|
|
833
777
|
}
|
|
834
778
|
|
|
835
779
|
function buildBootstrapHoldMessage(error, runtimeConfig = {}) {
|
|
836
|
-
if (error?.code === 'agent_code_conflict') {
|
|
837
|
-
const requestedAgentCode = normalizeClaworldText(
|
|
838
|
-
error?.context?.requestedAgentCode,
|
|
839
|
-
normalizeRuntimeRegistration(runtimeConfig).agentCode || null,
|
|
840
|
-
);
|
|
841
|
-
return requestedAgentCode
|
|
842
|
-
? `Claworld setup blocked: relay agent code ${requestedAgentCode} already exists. Add the bound appToken for this account or choose a different registration.agentCode.`
|
|
843
|
-
: 'Claworld setup blocked: relay agent code already exists. Add the bound appToken for this account or choose a different registration.agentCode.';
|
|
844
|
-
}
|
|
845
|
-
|
|
846
780
|
const publicMessage = normalizeClaworldText(error?.publicMessage, null);
|
|
847
781
|
const fallbackMessage = normalizeClaworldText(error?.message, 'relay binding bootstrap failed');
|
|
848
782
|
return `Claworld setup blocked: ${publicMessage || fallbackMessage}`;
|
|
@@ -970,6 +904,79 @@ async function fetchJson(fetchImpl, url, init = {}) {
|
|
|
970
904
|
}
|
|
971
905
|
}
|
|
972
906
|
|
|
907
|
+
async function fetchPublicIdentity({
|
|
908
|
+
runtimeConfig,
|
|
909
|
+
agentId = null,
|
|
910
|
+
fetchImpl,
|
|
911
|
+
}) {
|
|
912
|
+
const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
|
|
913
|
+
const path = buildRelayJsonPath('/v1/profile/public-identity', {
|
|
914
|
+
agentId,
|
|
915
|
+
});
|
|
916
|
+
const result = await fetchJson(fetchImpl, `${baseUrl}${path}`, {
|
|
917
|
+
method: 'GET',
|
|
918
|
+
headers: {
|
|
919
|
+
...(runtimeConfig.apiKey ? { 'x-api-key': runtimeConfig.apiKey } : {}),
|
|
920
|
+
...buildRuntimeAuthHeaders(runtimeConfig),
|
|
921
|
+
},
|
|
922
|
+
});
|
|
923
|
+
if (!result.ok) {
|
|
924
|
+
createRelayRouteError({
|
|
925
|
+
result,
|
|
926
|
+
runtimeConfig,
|
|
927
|
+
code: 'public_identity_fetch_failed',
|
|
928
|
+
publicMessage: 'failed to read public identity status',
|
|
929
|
+
context: { agentId: normalizeClaworldText(agentId, null) },
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
return result.body || {};
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
async function updatePublicIdentity({
|
|
936
|
+
runtimeConfig,
|
|
937
|
+
agentId = null,
|
|
938
|
+
displayName = null,
|
|
939
|
+
fetchImpl,
|
|
940
|
+
}) {
|
|
941
|
+
const normalizedDisplayName = normalizeClaworldText(displayName, null);
|
|
942
|
+
if (!normalizedDisplayName) {
|
|
943
|
+
throw createRuntimeBoundaryError({
|
|
944
|
+
code: 'tool_input_invalid',
|
|
945
|
+
category: 'input',
|
|
946
|
+
status: 400,
|
|
947
|
+
message: 'claworld public identity update requires displayName',
|
|
948
|
+
publicMessage: 'claworld public identity update requires displayName',
|
|
949
|
+
recoverable: true,
|
|
950
|
+
context: { field: 'displayName' },
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
|
|
954
|
+
const result = await fetchJson(fetchImpl, `${baseUrl}/v1/profile/public-identity`, {
|
|
955
|
+
method: 'PUT',
|
|
956
|
+
headers: {
|
|
957
|
+
'content-type': 'application/json',
|
|
958
|
+
...(runtimeConfig.apiKey ? { 'x-api-key': runtimeConfig.apiKey } : {}),
|
|
959
|
+
...buildRuntimeAuthHeaders(runtimeConfig),
|
|
960
|
+
},
|
|
961
|
+
body: JSON.stringify({
|
|
962
|
+
...(normalizeClaworldText(agentId, null) ? { agentId: normalizeClaworldText(agentId, null) } : {}),
|
|
963
|
+
displayName: normalizedDisplayName,
|
|
964
|
+
}),
|
|
965
|
+
});
|
|
966
|
+
if (!result.ok) {
|
|
967
|
+
createRelayRouteError({
|
|
968
|
+
result,
|
|
969
|
+
runtimeConfig,
|
|
970
|
+
code: 'public_identity_update_failed',
|
|
971
|
+
publicMessage: 'failed to update public identity',
|
|
972
|
+
context: {
|
|
973
|
+
agentId: normalizeClaworldText(agentId, null),
|
|
974
|
+
},
|
|
975
|
+
});
|
|
976
|
+
}
|
|
977
|
+
return result.body || {};
|
|
978
|
+
}
|
|
979
|
+
|
|
973
980
|
async function registerRelayBinding({ runtimeConfig, fetchImpl, logger }) {
|
|
974
981
|
if (typeof fetchImpl !== 'function') {
|
|
975
982
|
throw new Error('fetch is unavailable for relay registration');
|
|
@@ -985,7 +992,6 @@ async function registerRelayBinding({ runtimeConfig, fetchImpl, logger }) {
|
|
|
985
992
|
...(runtimeConfig.apiKey ? { 'x-api-key': runtimeConfig.apiKey } : {}),
|
|
986
993
|
}),
|
|
987
994
|
body: JSON.stringify({
|
|
988
|
-
...(registration.enabled ? { agentCode: registration.agentCode } : {}),
|
|
989
995
|
...(registration.displayName ? { displayName: registration.displayName } : {}),
|
|
990
996
|
}),
|
|
991
997
|
});
|
|
@@ -1007,11 +1013,7 @@ async function registerRelayBinding({ runtimeConfig, fetchImpl, logger }) {
|
|
|
1007
1013
|
: registerResult.status >= 500
|
|
1008
1014
|
? 'transport'
|
|
1009
1015
|
: 'config';
|
|
1010
|
-
const publicMessage =
|
|
1011
|
-
? 'relay agent code already exists; reuse its appToken or choose a different registration.agentCode'
|
|
1012
|
-
: errorCode === 'agent_code_mismatch'
|
|
1013
|
-
? 'configured relay agent code does not match the provided appToken'
|
|
1014
|
-
: 'relay registration failed';
|
|
1016
|
+
const publicMessage = 'relay registration failed';
|
|
1015
1017
|
|
|
1016
1018
|
throw createRuntimeBoundaryError({
|
|
1017
1019
|
code: errorCode,
|
|
@@ -1022,14 +1024,7 @@ async function registerRelayBinding({ runtimeConfig, fetchImpl, logger }) {
|
|
|
1022
1024
|
recoverable: registerResult.status >= 500,
|
|
1023
1025
|
context: {
|
|
1024
1026
|
accountId: runtimeConfig.accountId || null,
|
|
1025
|
-
requestedAgentCode: normalizeClaworldText(
|
|
1026
|
-
registerResult.body?.requestedAgentCode,
|
|
1027
|
-
registration.agentCode || null,
|
|
1028
|
-
),
|
|
1029
|
-
authenticatedAgentCode: normalizeClaworldText(registerResult.body?.authenticatedAgentCode, null),
|
|
1030
|
-
authenticatedAddress: normalizeClaworldText(registerResult.body?.authenticatedAddress, null),
|
|
1031
1027
|
conflictingAgentId: normalizeClaworldText(registerResult.body?.agent?.agentId, null),
|
|
1032
|
-
conflictingAddress: normalizeClaworldText(registerResult.body?.agent?.address, null),
|
|
1033
1028
|
appTokenConfigured: Boolean(resolveRuntimeAppToken(runtimeConfig)),
|
|
1034
1029
|
},
|
|
1035
1030
|
});
|
|
@@ -1085,67 +1080,30 @@ async function resolveRelayAgentSummary({
|
|
|
1085
1080
|
fetchImpl,
|
|
1086
1081
|
logger,
|
|
1087
1082
|
agentId = null,
|
|
1088
|
-
agentCode = null,
|
|
1089
|
-
address = null,
|
|
1090
1083
|
}) {
|
|
1091
|
-
const
|
|
1092
|
-
runtimeConfig,
|
|
1093
|
-
agentId,
|
|
1094
|
-
agentCode,
|
|
1095
|
-
address,
|
|
1096
|
-
});
|
|
1084
|
+
const normalizedAgentId = normalizeClaworldText(agentId, null);
|
|
1097
1085
|
|
|
1098
1086
|
try {
|
|
1099
1087
|
const items = await fetchRelayAgents({ runtimeConfig, fetchImpl, logger });
|
|
1100
1088
|
const match = items
|
|
1101
|
-
.map((item) => buildRelayAgentSummary(item
|
|
1102
|
-
.find((item) =>
|
|
1103
|
-
if (requestedIdentity.agentId && item.agentId === requestedIdentity.agentId) return true;
|
|
1104
|
-
if (requestedIdentity.agentCode && item.agentCode === requestedIdentity.agentCode) return true;
|
|
1105
|
-
if (requestedIdentity.address && item.address === requestedIdentity.address) return true;
|
|
1106
|
-
if (requestedIdentity.relayLocalCode && item.relayLocalCode === requestedIdentity.relayLocalCode) return true;
|
|
1107
|
-
return false;
|
|
1108
|
-
}) || null;
|
|
1089
|
+
.map((item) => buildRelayAgentSummary(item))
|
|
1090
|
+
.find((item) => normalizedAgentId && item.agentId === normalizedAgentId) || null;
|
|
1109
1091
|
|
|
1110
1092
|
if (match) {
|
|
1111
1093
|
return {
|
|
1112
1094
|
...match,
|
|
1113
1095
|
resolved: true,
|
|
1114
|
-
resolutionSource:
|
|
1115
|
-
? 'agentId'
|
|
1116
|
-
: requestedIdentity.agentCode && match.agentCode === requestedIdentity.agentCode
|
|
1117
|
-
? 'agentCode'
|
|
1118
|
-
: requestedIdentity.address && match.address === requestedIdentity.address
|
|
1119
|
-
? 'address'
|
|
1120
|
-
: 'relayLocalCode',
|
|
1096
|
+
resolutionSource: 'agentId',
|
|
1121
1097
|
};
|
|
1122
1098
|
}
|
|
1123
1099
|
} catch {
|
|
1124
1100
|
// Fallback below keeps pairing/send tools usable even when lookup fails.
|
|
1125
1101
|
}
|
|
1126
1102
|
|
|
1127
|
-
const canInferFallbackAgentCode = Boolean(
|
|
1128
|
-
requestedIdentity.agentCode
|
|
1129
|
-
|| requestedIdentity.address
|
|
1130
|
-
|| requestedIdentity.relayLocalCode,
|
|
1131
|
-
);
|
|
1132
|
-
const fallbackAgentCode = requestedIdentity.agentCode
|
|
1133
|
-
|| (canInferFallbackAgentCode ? buildCanonicalRelayAgentCode(runtimeConfig.localAgent?.agentCode, runtimeConfig) : null)
|
|
1134
|
-
|| (canInferFallbackAgentCode ? buildCanonicalRelayAgentCode(runtimeConfig.accountId, runtimeConfig) : null);
|
|
1135
|
-
const parsedFallbackAgentCode = parseCanonicalRelayAgentCode(fallbackAgentCode);
|
|
1136
|
-
|
|
1137
1103
|
return {
|
|
1138
|
-
agentId:
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|| parsedFallbackAgentCode?.relayLocalCode
|
|
1142
|
-
|| normalizeRelayLocalAgentCode(runtimeConfig.localAgent?.agentCode, null)
|
|
1143
|
-
|| null,
|
|
1144
|
-
domain: requestedIdentity.domain
|
|
1145
|
-
|| parsedFallbackAgentCode?.domain
|
|
1146
|
-
|| normalizeRelayDomainName(inferRelayDomain(runtimeConfig), null),
|
|
1147
|
-
address: requestedIdentity.address || fallbackAgentCode || null,
|
|
1148
|
-
displayName: normalizeClaworldText(runtimeConfig.localAgent?.displayName, null),
|
|
1104
|
+
agentId: normalizedAgentId,
|
|
1105
|
+
displayName: normalizeClaworldText(runtimeConfig.registration?.displayName, normalizeClaworldText(runtimeConfig.localAgent?.displayName, null)),
|
|
1106
|
+
publicIdentity: null,
|
|
1149
1107
|
discoverable: null,
|
|
1150
1108
|
contactable: null,
|
|
1151
1109
|
online: null,
|
|
@@ -1158,10 +1116,6 @@ async function ensureAgentPairing({ runtimeConfig, fetchImpl, logger }) {
|
|
|
1158
1116
|
const binding = await ensureRelayBinding({ runtimeConfig, fetchImpl, logger });
|
|
1159
1117
|
const pairedRuntimeConfig = binding.runtimeConfig;
|
|
1160
1118
|
const relayAgentId = normalizeClaworldText(pairedRuntimeConfig.relay?.agentId, null);
|
|
1161
|
-
const relayAgentCode = normalizeRelayLocalAgentCode(
|
|
1162
|
-
pairedRuntimeConfig.localAgent?.agentCode,
|
|
1163
|
-
normalizeRelayLocalAgentCode(pairedRuntimeConfig.accountId, null),
|
|
1164
|
-
);
|
|
1165
1119
|
|
|
1166
1120
|
if (!relayAgentId) {
|
|
1167
1121
|
return {
|
|
@@ -1174,7 +1128,6 @@ async function ensureAgentPairing({ runtimeConfig, fetchImpl, logger }) {
|
|
|
1174
1128
|
fetchImpl,
|
|
1175
1129
|
logger,
|
|
1176
1130
|
agentId: relayAgentId,
|
|
1177
|
-
agentCode: relayAgentCode,
|
|
1178
1131
|
}),
|
|
1179
1132
|
};
|
|
1180
1133
|
}
|
|
@@ -1184,14 +1137,13 @@ async function ensureAgentPairing({ runtimeConfig, fetchImpl, logger }) {
|
|
|
1184
1137
|
reason: null,
|
|
1185
1138
|
bindingSource: binding.bindingSource,
|
|
1186
1139
|
runtimeConfig: pairedRuntimeConfig,
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
}
|
|
1194
|
-
};
|
|
1140
|
+
relayAgent: await resolveRelayAgentSummary({
|
|
1141
|
+
runtimeConfig: pairedRuntimeConfig,
|
|
1142
|
+
fetchImpl,
|
|
1143
|
+
logger,
|
|
1144
|
+
agentId: relayAgentId,
|
|
1145
|
+
}),
|
|
1146
|
+
};
|
|
1195
1147
|
}
|
|
1196
1148
|
|
|
1197
1149
|
async function fetchPostSetupWorldDirectory({ cfg, accountId, runtimeConfig, limit = null, sort = null, page = null, fetchImpl, logger }) {
|
|
@@ -1248,7 +1200,7 @@ async function ensureRelayBinding({ runtimeConfig, fetchImpl, logger }) {
|
|
|
1248
1200
|
serverUrl: normalizedRuntimeConfig.serverUrl,
|
|
1249
1201
|
appTokenConfigured: Boolean(appToken),
|
|
1250
1202
|
registrationEnabled: registration.enabled,
|
|
1251
|
-
|
|
1203
|
+
displayName: registration.displayName || null,
|
|
1252
1204
|
hasRelayAgentId: Boolean(normalizedRuntimeConfig.relay?.agentId),
|
|
1253
1205
|
});
|
|
1254
1206
|
|
|
@@ -1273,10 +1225,12 @@ function buildDeliveryInboundEnvelope({
|
|
|
1273
1225
|
incomingText,
|
|
1274
1226
|
contextText = null,
|
|
1275
1227
|
commandText = null,
|
|
1228
|
+
timestamp = null,
|
|
1276
1229
|
deliveryId,
|
|
1277
1230
|
sessionKey,
|
|
1278
1231
|
worldId = null,
|
|
1279
1232
|
conversationKey = null,
|
|
1233
|
+
untrustedContext = [],
|
|
1280
1234
|
}) {
|
|
1281
1235
|
const envelopeOptions = runtime?.channel?.reply?.resolveEnvelopeFormatOptions
|
|
1282
1236
|
? runtime.channel.reply.resolveEnvelopeFormatOptions(currentCfg)
|
|
@@ -1286,37 +1240,43 @@ function buildDeliveryInboundEnvelope({
|
|
|
1286
1240
|
String(incomingText || '').trim(),
|
|
1287
1241
|
].filter(Boolean).join('\n\n');
|
|
1288
1242
|
const remoteLabel = String(remoteIdentity || 'unknown-peer').trim() || 'unknown-peer';
|
|
1289
|
-
const
|
|
1243
|
+
const rawBody = String(incomingText || '').trim();
|
|
1244
|
+
const normalizedCommandText = String(commandText || '').trim();
|
|
1245
|
+
const commandBody = normalizedCommandText || rawBody;
|
|
1246
|
+
const bodyForAgent = bodyText || rawBody;
|
|
1247
|
+
const contextLines = mergeUntrustedContextLines([
|
|
1290
1248
|
`[claworld peer ${remoteLabel}]`,
|
|
1291
1249
|
...(worldId ? [`[claworld world ${worldId}]`] : []),
|
|
1292
1250
|
...(conversationKey ? [`[claworld conversation ${conversationKey}]`] : []),
|
|
1293
1251
|
`[claworld session ${sessionKey}]`,
|
|
1294
1252
|
`[claworld delivery ${deliveryId}]`,
|
|
1295
|
-
];
|
|
1296
|
-
const
|
|
1297
|
-
const normalizedCommandText = String(commandText || '').trim();
|
|
1298
|
-
const commandBody = normalizedCommandText || rawBody;
|
|
1253
|
+
], untrustedContext);
|
|
1254
|
+
const envelopeTimestamp = Number.isFinite(timestamp) ? new Date(timestamp) : new Date();
|
|
1299
1255
|
|
|
1300
1256
|
if (runtime?.channel?.reply?.formatAgentEnvelope) {
|
|
1301
1257
|
return {
|
|
1302
1258
|
Body: runtime.channel.reply.formatAgentEnvelope({
|
|
1303
1259
|
channel: 'Claworld',
|
|
1304
1260
|
from: remoteLabel,
|
|
1305
|
-
timestamp:
|
|
1261
|
+
timestamp: envelopeTimestamp,
|
|
1306
1262
|
envelope: envelopeOptions,
|
|
1307
|
-
body:
|
|
1263
|
+
body: bodyForAgent,
|
|
1308
1264
|
}),
|
|
1309
1265
|
RawBody: rawBody,
|
|
1310
1266
|
CommandBody: commandBody,
|
|
1311
|
-
|
|
1267
|
+
BodyForAgent: bodyForAgent,
|
|
1268
|
+
BodyForCommands: commandBody,
|
|
1269
|
+
UntrustedContext: contextLines,
|
|
1312
1270
|
};
|
|
1313
1271
|
}
|
|
1314
1272
|
|
|
1315
1273
|
return {
|
|
1316
|
-
Body: `${remoteLabel}: ${
|
|
1274
|
+
Body: `${remoteLabel}: ${bodyForAgent}`,
|
|
1317
1275
|
RawBody: rawBody,
|
|
1318
1276
|
CommandBody: commandBody,
|
|
1319
|
-
|
|
1277
|
+
BodyForAgent: bodyForAgent,
|
|
1278
|
+
BodyForCommands: commandBody,
|
|
1279
|
+
UntrustedContext: contextLines,
|
|
1320
1280
|
};
|
|
1321
1281
|
}
|
|
1322
1282
|
|
|
@@ -1678,15 +1638,14 @@ async function maybeBridgeRuntimeDelivery({
|
|
|
1678
1638
|
: {};
|
|
1679
1639
|
const deliveryId = resolveNormalizedText(delivery.deliveryId, null);
|
|
1680
1640
|
const sessionKey = resolveNormalizedText(delivery.sessionKey, null);
|
|
1681
|
-
const
|
|
1682
|
-
const
|
|
1641
|
+
const contextText = resolveNormalizedText(payload.contextText, null);
|
|
1642
|
+
const incomingText = resolveNormalizedText(
|
|
1643
|
+
payload.commandText,
|
|
1644
|
+
contextText ? null : resolveNormalizedText(payload.text, null),
|
|
1645
|
+
);
|
|
1646
|
+
const commandText = resolveNormalizedText(payload.commandText, incomingText);
|
|
1683
1647
|
const fromAgentId = resolveNormalizedText(metadata.fromAgentId, null);
|
|
1684
|
-
const
|
|
1685
|
-
|| resolveRelayAddress(fromAgentId || '', runtimeConfig)
|
|
1686
|
-
|| fromAgentId
|
|
1687
|
-
|| 'unknown-peer';
|
|
1688
|
-
const remoteRouteIdentity = resolveRelayAddress(fromAgentId || '', runtimeConfig)
|
|
1689
|
-
|| remoteAddress;
|
|
1648
|
+
const remoteIdentity = fromAgentId || 'unknown-peer';
|
|
1690
1649
|
|
|
1691
1650
|
if (
|
|
1692
1651
|
!runtime?.channel?.reply?.finalizeInboundContext
|
|
@@ -1699,11 +1658,12 @@ async function maybeBridgeRuntimeDelivery({
|
|
|
1699
1658
|
});
|
|
1700
1659
|
return { skipped: true, reason: 'missing_runtime_bridge_hooks' };
|
|
1701
1660
|
}
|
|
1702
|
-
if (!deliveryId || !sessionKey || !incomingText) {
|
|
1661
|
+
if (!deliveryId || !sessionKey || (!incomingText && !contextText)) {
|
|
1703
1662
|
logger.warn?.(`[claworld:${runtimeAccountId}] skipping delivery bridge: missing delivery payload`, {
|
|
1704
1663
|
deliveryId,
|
|
1705
1664
|
sessionKey,
|
|
1706
1665
|
hasIncomingText: Boolean(incomingText),
|
|
1666
|
+
hasContextText: Boolean(contextText),
|
|
1707
1667
|
});
|
|
1708
1668
|
return { skipped: true, reason: 'missing_delivery_payload' };
|
|
1709
1669
|
}
|
|
@@ -1716,48 +1676,51 @@ async function maybeBridgeRuntimeDelivery({
|
|
|
1716
1676
|
const worldId = resolveDeliveryWorldId(delivery);
|
|
1717
1677
|
const commandAuthorized = shouldAuthorizeBridgedCommand({
|
|
1718
1678
|
runtimeConfig,
|
|
1719
|
-
incomingText,
|
|
1679
|
+
incomingText: commandText || incomingText,
|
|
1720
1680
|
});
|
|
1721
|
-
const
|
|
1681
|
+
const inboundTimestamp = resolveBridgeDeliveryTimestampMs({ delivery, metadata });
|
|
1682
|
+
const { Body, RawBody, CommandBody, BodyForAgent, BodyForCommands, UntrustedContext } = buildDeliveryInboundEnvelope({
|
|
1722
1683
|
runtime,
|
|
1723
1684
|
currentCfg,
|
|
1724
|
-
remoteIdentity
|
|
1685
|
+
remoteIdentity,
|
|
1725
1686
|
incomingText,
|
|
1726
1687
|
contextText,
|
|
1727
|
-
commandText
|
|
1688
|
+
commandText,
|
|
1689
|
+
timestamp: inboundTimestamp,
|
|
1728
1690
|
deliveryId,
|
|
1729
1691
|
sessionKey,
|
|
1730
1692
|
worldId,
|
|
1731
1693
|
conversationKey: metadata.conversationKey || null,
|
|
1694
|
+
untrustedContext: payload.untrustedContext,
|
|
1732
1695
|
});
|
|
1733
|
-
const
|
|
1696
|
+
const localIdentity = normalizeClaworldText(runtimeConfig.relay?.agentId, runtimeConfig.accountId);
|
|
1734
1697
|
const inboundCtx = runtime.channel.reply.finalizeInboundContext({
|
|
1735
1698
|
Body,
|
|
1736
1699
|
RawBody,
|
|
1737
1700
|
CommandBody,
|
|
1738
|
-
BodyForAgent
|
|
1739
|
-
BodyForCommands
|
|
1740
|
-
From: `claworld:${
|
|
1741
|
-
To:
|
|
1701
|
+
BodyForAgent,
|
|
1702
|
+
BodyForCommands,
|
|
1703
|
+
From: `claworld:${remoteIdentity}`,
|
|
1704
|
+
To: `claworld:${localIdentity}`,
|
|
1742
1705
|
SessionKey: sessionKey,
|
|
1743
1706
|
AccountId: runtimeConfig.accountId,
|
|
1744
1707
|
OriginatingChannel: 'claworld',
|
|
1745
|
-
OriginatingFrom:
|
|
1746
|
-
OriginatingTo:
|
|
1708
|
+
OriginatingFrom: remoteIdentity,
|
|
1709
|
+
OriginatingTo: remoteIdentity,
|
|
1747
1710
|
ChatType: 'direct',
|
|
1748
|
-
SenderName:
|
|
1749
|
-
SenderId:
|
|
1711
|
+
SenderName: remoteIdentity,
|
|
1712
|
+
SenderId: remoteIdentity,
|
|
1750
1713
|
MessageId: deliveryId,
|
|
1751
1714
|
Provider: 'claworld',
|
|
1752
1715
|
Surface: 'claworld',
|
|
1753
|
-
ConversationLabel:
|
|
1754
|
-
Timestamp:
|
|
1716
|
+
ConversationLabel: remoteIdentity,
|
|
1717
|
+
Timestamp: inboundTimestamp,
|
|
1755
1718
|
MessageSid: deliveryId,
|
|
1756
1719
|
WasMentioned: false,
|
|
1757
1720
|
CommandAuthorized: commandAuthorized,
|
|
1758
1721
|
RelayDeliveryId: deliveryId,
|
|
1759
1722
|
RelayFromAgentId: fromAgentId,
|
|
1760
|
-
UntrustedContext
|
|
1723
|
+
UntrustedContext,
|
|
1761
1724
|
});
|
|
1762
1725
|
const localAgentId = resolveBoundLocalAgentId({
|
|
1763
1726
|
cfg: currentCfg,
|
|
@@ -1788,7 +1751,7 @@ async function maybeBridgeRuntimeDelivery({
|
|
|
1788
1751
|
deliveryId,
|
|
1789
1752
|
sessionKey,
|
|
1790
1753
|
localAgentId,
|
|
1791
|
-
remoteIdentity
|
|
1754
|
+
remoteIdentity,
|
|
1792
1755
|
routeStatus: routed?.status || null,
|
|
1793
1756
|
bodyPreview: String(Body || '').slice(0, 240),
|
|
1794
1757
|
rawBodyPreview: String(RawBody || '').slice(0, 240),
|
|
@@ -1796,6 +1759,23 @@ async function maybeBridgeRuntimeDelivery({
|
|
|
1796
1759
|
commandAuthorized,
|
|
1797
1760
|
});
|
|
1798
1761
|
|
|
1762
|
+
try {
|
|
1763
|
+
if (typeof relayClient?.sendAcceptedAndWaitForAck === 'function') {
|
|
1764
|
+
await relayClient.sendAcceptedAndWaitForAck({
|
|
1765
|
+
deliveryId,
|
|
1766
|
+
sessionKey,
|
|
1767
|
+
source: 'runtime_dispatch',
|
|
1768
|
+
});
|
|
1769
|
+
}
|
|
1770
|
+
} catch (error) {
|
|
1771
|
+
logger.warn?.(`[claworld:${runtimeAccountId}] delivery acceptance acknowledgement failed`, {
|
|
1772
|
+
deliveryId,
|
|
1773
|
+
sessionKey,
|
|
1774
|
+
localAgentId,
|
|
1775
|
+
error: error?.message || String(error),
|
|
1776
|
+
});
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1799
1779
|
let {
|
|
1800
1780
|
dispatchResult,
|
|
1801
1781
|
replied,
|
|
@@ -2349,9 +2329,9 @@ export function createClaworldChannelPlugin({
|
|
|
2349
2329
|
},
|
|
2350
2330
|
agentPrompt: {
|
|
2351
2331
|
messageToolHints: () => [
|
|
2352
|
-
'- Claworld targets are canonical
|
|
2332
|
+
'- Claworld message targets are canonical `agentId` values such as `agt_xxx`.',
|
|
2353
2333
|
'- Omit `target` to keep replying inside the current A2A session when the runtime already inferred the peer.',
|
|
2354
|
-
'-
|
|
2334
|
+
'- Resolve public identity like `displayName#code` to `agentId` before opening a new relay session to another agent.',
|
|
2355
2335
|
],
|
|
2356
2336
|
},
|
|
2357
2337
|
reload: { configPrefixes: ['channels.claworld'] },
|
|
@@ -2383,19 +2363,18 @@ export function createClaworldChannelPlugin({
|
|
|
2383
2363
|
looksLikeId: (raw, normalized) => {
|
|
2384
2364
|
const value = String(normalized || raw || '').trim();
|
|
2385
2365
|
if (!value) return false;
|
|
2386
|
-
|
|
2387
|
-
return /^[a-z0-9._:+~-]+$/i.test(value) || /^agt_[a-z0-9_-]+$/i.test(value);
|
|
2366
|
+
return /^agt_[a-z0-9_-]+$/i.test(value);
|
|
2388
2367
|
},
|
|
2389
|
-
hint: '<
|
|
2368
|
+
hint: '<agentId>',
|
|
2390
2369
|
},
|
|
2391
2370
|
},
|
|
2392
2371
|
directory: {
|
|
2393
2372
|
self: async ({ cfg, accountId } = {}) => {
|
|
2394
2373
|
const account = inspectClaworldChannelAccount(cfg || {}, accountId || null);
|
|
2395
|
-
const
|
|
2396
|
-
if (!account?.configured || !
|
|
2374
|
+
const agentId = normalizeClaworldText(account?.relay?.agentId, null);
|
|
2375
|
+
if (!account?.configured || !agentId) return null;
|
|
2397
2376
|
return {
|
|
2398
|
-
id:
|
|
2377
|
+
id: agentId,
|
|
2399
2378
|
name: account.accountId,
|
|
2400
2379
|
handle: account.accountId,
|
|
2401
2380
|
};
|
|
@@ -2478,8 +2457,6 @@ export function createClaworldChannelPlugin({
|
|
|
2478
2457
|
fetchImpl,
|
|
2479
2458
|
logger,
|
|
2480
2459
|
agentId: context.agentId || context.targetAgentId || null,
|
|
2481
|
-
agentCode: context.agentCode || context.targetAgentCode || null,
|
|
2482
|
-
address: context.address || null,
|
|
2483
2460
|
}),
|
|
2484
2461
|
},
|
|
2485
2462
|
social: {
|
|
@@ -2488,7 +2465,7 @@ export function createClaworldChannelPlugin({
|
|
|
2488
2465
|
return createFriendRequest({
|
|
2489
2466
|
runtimeConfig: resolvedContext.runtimeConfig,
|
|
2490
2467
|
fromAgentId: resolvedContext.agentId || null,
|
|
2491
|
-
|
|
2468
|
+
targetAgentId: context.targetAgentId || null,
|
|
2492
2469
|
message: context.message || null,
|
|
2493
2470
|
metadata: context.metadata || {},
|
|
2494
2471
|
fetchImpl,
|
|
@@ -2578,6 +2555,25 @@ export function createClaworldChannelPlugin({
|
|
|
2578
2555
|
});
|
|
2579
2556
|
},
|
|
2580
2557
|
},
|
|
2558
|
+
profile: {
|
|
2559
|
+
getPublicIdentity: async (context = {}) => {
|
|
2560
|
+
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
2561
|
+
return fetchPublicIdentity({
|
|
2562
|
+
runtimeConfig: resolvedContext.runtimeConfig,
|
|
2563
|
+
agentId: resolvedContext.agentId || null,
|
|
2564
|
+
fetchImpl,
|
|
2565
|
+
});
|
|
2566
|
+
},
|
|
2567
|
+
updatePublicIdentity: async (context = {}) => {
|
|
2568
|
+
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
2569
|
+
return updatePublicIdentity({
|
|
2570
|
+
runtimeConfig: resolvedContext.runtimeConfig,
|
|
2571
|
+
agentId: resolvedContext.agentId || null,
|
|
2572
|
+
displayName: context.displayName || null,
|
|
2573
|
+
fetchImpl,
|
|
2574
|
+
});
|
|
2575
|
+
},
|
|
2576
|
+
},
|
|
2581
2577
|
postSetup: {
|
|
2582
2578
|
fetchWorldDirectory: async (context = {}) => {
|
|
2583
2579
|
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
@@ -2686,7 +2682,7 @@ export function createClaworldChannelPlugin({
|
|
|
2686
2682
|
agentId: resolvedContext.agentId || null,
|
|
2687
2683
|
displayName: context.displayName || null,
|
|
2688
2684
|
worldContextText: context.worldContextText || null,
|
|
2689
|
-
enabled: context.enabled === true,
|
|
2685
|
+
enabled: typeof context.enabled === 'boolean' ? context.enabled : true,
|
|
2690
2686
|
fetchImpl,
|
|
2691
2687
|
logger,
|
|
2692
2688
|
});
|
|
@@ -2728,6 +2724,25 @@ export function createClaworldChannelPlugin({
|
|
|
2728
2724
|
results,
|
|
2729
2725
|
demo,
|
|
2730
2726
|
productShell: {
|
|
2727
|
+
profile: {
|
|
2728
|
+
getPublicIdentity: async (context = {}) => {
|
|
2729
|
+
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
2730
|
+
return fetchPublicIdentity({
|
|
2731
|
+
runtimeConfig: resolvedContext.runtimeConfig || null,
|
|
2732
|
+
agentId: resolvedContext.agentId || null,
|
|
2733
|
+
fetchImpl,
|
|
2734
|
+
});
|
|
2735
|
+
},
|
|
2736
|
+
updatePublicIdentity: async (context = {}) => {
|
|
2737
|
+
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
2738
|
+
return updatePublicIdentity({
|
|
2739
|
+
runtimeConfig: resolvedContext.runtimeConfig || null,
|
|
2740
|
+
agentId: resolvedContext.agentId || null,
|
|
2741
|
+
displayName: context.displayName || null,
|
|
2742
|
+
fetchImpl,
|
|
2743
|
+
});
|
|
2744
|
+
},
|
|
2745
|
+
},
|
|
2731
2746
|
fetchWorldDirectory: async (context = {}) => {
|
|
2732
2747
|
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
2733
2748
|
return fetchPostSetupWorldDirectory({
|
|
@@ -2868,14 +2883,14 @@ export function createClaworldChannelPlugin({
|
|
|
2868
2883
|
moderation: {
|
|
2869
2884
|
createWorld: async (context = {}) => {
|
|
2870
2885
|
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
2871
|
-
|
|
2886
|
+
return createModeratedWorld({
|
|
2872
2887
|
cfg: resolvedContext.cfg || {},
|
|
2873
2888
|
accountId: resolvedContext.accountId || null,
|
|
2874
2889
|
runtimeConfig: resolvedContext.runtimeConfig || null,
|
|
2875
2890
|
agentId: resolvedContext.agentId || null,
|
|
2876
2891
|
displayName: context.displayName || null,
|
|
2877
2892
|
worldContextText: context.worldContextText || null,
|
|
2878
|
-
enabled: context.enabled === true,
|
|
2893
|
+
enabled: typeof context.enabled === 'boolean' ? context.enabled : true,
|
|
2879
2894
|
fetchImpl,
|
|
2880
2895
|
logger,
|
|
2881
2896
|
});
|