@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.
@@ -1,3 +1,5 @@
1
+ import { randomUUID } from 'node:crypto';
2
+
1
3
  import {
2
4
  applyRuntimeIdentity,
3
5
  buildRuntimeAuthHeaders,
@@ -74,6 +76,10 @@ function requireClientMessageId(value = null) {
74
76
  return normalized;
75
77
  }
76
78
 
79
+ function buildGeneratedClientMessageId() {
80
+ return `openclaw_manual_${randomUUID()}`;
81
+ }
82
+
77
83
  function buildRelayAgentSummary(item = {}) {
78
84
  const normalizedAgentId = normalizeClaworldText(item?.agentId, null);
79
85
  return {
@@ -338,9 +344,9 @@ async function deliverRelayMessage({ runtimeConfig, to, text, fetchImpl, logger,
338
344
  }
339
345
  payload.source = normalizeClaworldText(payload.source, 'openclaw-claworld');
340
346
  payload.accountId = normalizeClaworldText(payload.accountId, runtimeConfig.accountId);
341
- const clientMessageId = requireClientMessageId(
347
+ const clientMessageId = normalizePluginOptionalText(
342
348
  outboundContext.clientMessageId || outboundContext.metadata?.clientMessageId || null
343
- );
349
+ ) || buildGeneratedClientMessageId();
344
350
 
345
351
  const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
346
352
  const result = await fetchJson(fetchImpl, `${baseUrl}/v1/messages`, {
@@ -436,22 +442,24 @@ function createRelayRouteError({
436
442
  async function createChatRequest({
437
443
  runtimeConfig,
438
444
  fromAgentId,
439
- targetAgentId,
445
+ displayName = null,
446
+ agentCode = null,
440
447
  openingMessage = null,
441
448
  worldId = null,
442
449
  requestContext = null,
443
450
  fetchImpl,
444
451
  }) {
445
- const normalizedTargetAgentId = normalizeClaworldText(targetAgentId, null);
446
- if (!normalizedTargetAgentId) {
452
+ const normalizedDisplayName = normalizeClaworldText(displayName, null);
453
+ const normalizedAgentCode = normalizeClaworldText(agentCode, null)?.toUpperCase() || null;
454
+ if (!normalizedDisplayName || !normalizedAgentCode) {
447
455
  throw createRuntimeBoundaryError({
448
456
  code: 'tool_input_invalid',
449
457
  category: 'input',
450
458
  status: 400,
451
- message: 'claworld chat request target requires targetAgentId',
452
- publicMessage: 'claworld chat request target requires targetAgentId',
459
+ message: 'claworld chat request target requires displayName and agentCode',
460
+ publicMessage: 'claworld chat request target requires displayName and agentCode',
453
461
  recoverable: true,
454
- context: { field: 'targetAgentId' },
462
+ context: { fields: ['displayName', 'agentCode'] },
455
463
  });
456
464
  }
457
465
  const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
@@ -464,7 +472,8 @@ async function createChatRequest({
464
472
  },
465
473
  body: JSON.stringify({
466
474
  fromAgentId,
467
- targetAgentId: normalizedTargetAgentId,
475
+ displayName: normalizedDisplayName,
476
+ agentCode: normalizedAgentCode,
468
477
  openingMessage: normalizeClaworldText(openingMessage, null),
469
478
  ...(normalizeClaworldText(worldId, null) ? { worldId: normalizeClaworldText(worldId, null) } : {}),
470
479
  ...(requestContext && typeof requestContext === 'object' && !Array.isArray(requestContext)
@@ -478,7 +487,11 @@ async function createChatRequest({
478
487
  runtimeConfig,
479
488
  code: 'chat_request_create_failed',
480
489
  publicMessage: 'failed to create chat request',
481
- context: { fromAgentId, targetAgentId: normalizedTargetAgentId },
490
+ context: {
491
+ fromAgentId,
492
+ displayName: normalizedDisplayName,
493
+ agentCode: normalizedAgentCode,
494
+ },
482
495
  });
483
496
  }
484
497
  return result.body || {};
@@ -570,62 +583,6 @@ async function rejectChatRequest({
570
583
  return result.body || {};
571
584
  }
572
585
 
573
- async function syncChatRequestApprovalPolicy({
574
- runtimeConfig,
575
- fetchImpl,
576
- logger,
577
- }) {
578
- const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
579
- let result;
580
- try {
581
- result = await fetchJson(fetchImpl, `${baseUrl}/v1/chat-requests/approval-policy`, {
582
- method: 'PUT',
583
- headers: {
584
- 'content-type': 'application/json',
585
- ...(runtimeConfig.apiKey ? { 'x-api-key': runtimeConfig.apiKey } : {}),
586
- ...buildRuntimeAuthHeaders(runtimeConfig),
587
- },
588
- body: JSON.stringify({
589
- accountId: runtimeConfig.accountId || null,
590
- approval: runtimeConfig.approval || {},
591
- }),
592
- });
593
- } catch (error) {
594
- logger.warn?.(`[claworld:${runtimeConfig.accountId || 'default'}] approval policy sync failed`, {
595
- error: error?.message || String(error),
596
- code: error?.code || null,
597
- category: error?.category || null,
598
- });
599
- return {
600
- ok: false,
601
- status: error?.status || null,
602
- body: null,
603
- error,
604
- };
605
- }
606
- if (!result.ok) {
607
- logger.warn?.(`[claworld:${runtimeConfig.accountId || 'default'}] approval policy sync failed`, {
608
- status: result.status,
609
- body: result.body,
610
- });
611
- return {
612
- ok: false,
613
- status: result.status,
614
- body: result.body,
615
- };
616
- }
617
-
618
- logger.info?.(`[claworld:${runtimeConfig.accountId || 'default'}] approval policy sync ok`, {
619
- mode: result.body?.approvalPolicy?.policy?.mode || runtimeConfig.approval?.mode || null,
620
- syncedAt: result.body?.approvalPolicy?.syncedAt || null,
621
- });
622
- return {
623
- ok: true,
624
- status: result.status,
625
- body: result.body,
626
- };
627
- }
628
-
629
586
  function waitForAbort(signal) {
630
587
  return new Promise((resolve) => {
631
588
  if (!signal) return resolve({ reason: 'missing_abort_signal' });
@@ -828,6 +785,7 @@ async function fetchPublicIdentity({
828
785
  totalLikesGiven: 0,
829
786
  totalDislikesGiven: 0,
830
787
  },
788
+ profile: null,
831
789
  };
832
790
  }
833
791
 
@@ -840,6 +798,7 @@ async function fetchPublicIdentity({
840
798
  ...buildRuntimeAuthHeaders(runtimeConfig),
841
799
  },
842
800
  body: JSON.stringify({
801
+ accountId: runtimeConfig.accountId || null,
843
802
  ...(agentId ? { agentId } : {}),
844
803
  action: 'view',
845
804
  ...(generateShareCard === true ? { generateShareCard: true } : {}),
@@ -934,6 +893,7 @@ async function updatePublicIdentity({
934
893
  ...buildRuntimeAuthHeaders(resolvedRuntimeConfig),
935
894
  },
936
895
  body: JSON.stringify({
896
+ accountId: resolvedRuntimeConfig.accountId || null,
937
897
  ...(resolvedAgentId ? { agentId: resolvedAgentId } : {}),
938
898
  action: 'update_identity',
939
899
  displayName: normalizedDisplayName,
@@ -966,6 +926,100 @@ async function updatePublicIdentity({
966
926
  };
967
927
  }
968
928
 
929
+ async function updateChatRequestApprovalPolicy({
930
+ runtimeConfig,
931
+ agentId = null,
932
+ chatRequestApprovalPolicy = null,
933
+ fetchImpl,
934
+ }) {
935
+ if (!resolveRuntimeAppToken(runtimeConfig)) {
936
+ throw createRuntimeBoundaryError({
937
+ code: 'claworld_account_unactivated',
938
+ category: 'conflict',
939
+ status: 409,
940
+ message: 'claworld account must be activated before updating chat policy',
941
+ publicMessage: 'activate the Claworld account before changing chat policy',
942
+ recoverable: true,
943
+ });
944
+ }
945
+
946
+ const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
947
+ const result = await fetchJson(fetchImpl, `${baseUrl}/v1/profile`, {
948
+ method: 'POST',
949
+ headers: {
950
+ 'content-type': 'application/json',
951
+ ...(runtimeConfig.apiKey ? { 'x-api-key': runtimeConfig.apiKey } : {}),
952
+ ...buildRuntimeAuthHeaders(runtimeConfig),
953
+ },
954
+ body: JSON.stringify({
955
+ accountId: runtimeConfig.accountId || null,
956
+ ...(agentId ? { agentId } : {}),
957
+ action: 'update_chat_policy',
958
+ chatRequestApprovalPolicy,
959
+ }),
960
+ });
961
+ if (!result.ok) {
962
+ createRelayRouteError({
963
+ result,
964
+ runtimeConfig,
965
+ code: 'chat_request_approval_policy_update_failed',
966
+ publicMessage: 'failed to update chat policy',
967
+ context: {
968
+ accountId: runtimeConfig.accountId || null,
969
+ agentId: normalizeClaworldText(agentId, null),
970
+ },
971
+ });
972
+ }
973
+ return result.body || {};
974
+ }
975
+
976
+ async function updateGlobalProfile({
977
+ runtimeConfig,
978
+ agentId = null,
979
+ profile = '',
980
+ fetchImpl,
981
+ }) {
982
+ if (!resolveRuntimeAppToken(runtimeConfig)) {
983
+ throw createRuntimeBoundaryError({
984
+ code: 'claworld_account_unactivated',
985
+ category: 'conflict',
986
+ status: 409,
987
+ message: 'claworld account must be activated before updating profile',
988
+ publicMessage: 'activate the Claworld account before updating profile',
989
+ recoverable: true,
990
+ });
991
+ }
992
+
993
+ const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
994
+ const result = await fetchJson(fetchImpl, `${baseUrl}/v1/profile`, {
995
+ method: 'POST',
996
+ headers: {
997
+ 'content-type': 'application/json',
998
+ ...(runtimeConfig.apiKey ? { 'x-api-key': runtimeConfig.apiKey } : {}),
999
+ ...buildRuntimeAuthHeaders(runtimeConfig),
1000
+ },
1001
+ body: JSON.stringify({
1002
+ accountId: runtimeConfig.accountId || null,
1003
+ ...(agentId ? { agentId } : {}),
1004
+ action: 'update_profile',
1005
+ profile,
1006
+ }),
1007
+ });
1008
+ if (!result.ok) {
1009
+ createRelayRouteError({
1010
+ result,
1011
+ runtimeConfig,
1012
+ code: 'profile_update_failed',
1013
+ publicMessage: 'failed to update profile',
1014
+ context: {
1015
+ accountId: runtimeConfig.accountId || null,
1016
+ agentId: normalizeClaworldText(agentId, null),
1017
+ },
1018
+ });
1019
+ }
1020
+ return result.body || {};
1021
+ }
1022
+
969
1023
  async function renderAgentCard({
970
1024
  runtimeConfig,
971
1025
  agentId = null,
@@ -1020,78 +1074,6 @@ async function renderAgentCard({
1020
1074
  return result.body || {};
1021
1075
  }
1022
1076
 
1023
- async function registerRelayBinding({ runtimeConfig, fetchImpl, logger }) {
1024
- if (typeof fetchImpl !== 'function') {
1025
- throw new Error('fetch is unavailable for relay registration');
1026
- }
1027
-
1028
- const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
1029
- const registration = normalizeRuntimeRegistration(runtimeConfig);
1030
- const registerResult = await fetchJson(fetchImpl, `${baseUrl}/v1/agents/register`, {
1031
- method: 'POST',
1032
- headers: buildRuntimeAuthHeaders(runtimeConfig, {
1033
- accept: 'application/json',
1034
- 'content-type': 'application/json',
1035
- ...(runtimeConfig.apiKey ? { 'x-api-key': runtimeConfig.apiKey } : {}),
1036
- }),
1037
- body: JSON.stringify({
1038
- ...(registration.displayName ? { displayName: registration.displayName } : {}),
1039
- }),
1040
- });
1041
-
1042
- if (!registerResult.ok) {
1043
- logger.error?.('[claworld:bootstrap] register relay agent failed', {
1044
- accountId: runtimeConfig.accountId,
1045
- status: registerResult.status,
1046
- body: registerResult.body,
1047
- });
1048
-
1049
- const errorCode = normalizeClaworldText(registerResult.body?.error, 'relay_agent_registration_failed');
1050
- const category = registerResult.status === 401
1051
- ? 'auth'
1052
- : registerResult.status === 403
1053
- ? 'policy'
1054
- : registerResult.status === 409
1055
- ? 'conflict'
1056
- : registerResult.status >= 500
1057
- ? 'transport'
1058
- : 'config';
1059
- const publicMessage = 'relay registration failed';
1060
-
1061
- throw createRuntimeBoundaryError({
1062
- code: errorCode,
1063
- category,
1064
- status: registerResult.status,
1065
- message: `failed to register relay agent: ${registerResult.status}`,
1066
- publicMessage,
1067
- recoverable: registerResult.status >= 500,
1068
- context: {
1069
- accountId: runtimeConfig.accountId || null,
1070
- conflictingAgentId: normalizeClaworldText(registerResult.body?.agent?.agentId, null),
1071
- appTokenConfigured: Boolean(resolveRuntimeAppToken(runtimeConfig)),
1072
- },
1073
- });
1074
- }
1075
-
1076
- const registeredAgent = registerResult.body?.agent || null;
1077
- const appToken = normalizeClaworldText(registerResult.body?.appToken, resolveRuntimeAppToken(runtimeConfig));
1078
- if (!registeredAgent?.agentId || !appToken) {
1079
- throw new Error('relay registration did not produce relay agent binding');
1080
- }
1081
-
1082
- return {
1083
- bindingSource: normalizeClaworldText(
1084
- registerResult.body?.bindingSource,
1085
- resolveRuntimeAppToken(runtimeConfig) ? 'provided_app_token' : 'created_agent_app_token',
1086
- ),
1087
- runtimeConfig: applyRuntimeIdentity(runtimeConfig, {
1088
- agentId: registeredAgent.agentId,
1089
- appToken,
1090
- }),
1091
- relayAgent: buildRelayAgentSummary(registeredAgent, runtimeConfig),
1092
- };
1093
- }
1094
-
1095
1077
  async function fetchRelayAgents({ runtimeConfig, fetchImpl, logger }) {
1096
1078
  if (typeof fetchImpl !== 'function') {
1097
1079
  throw new Error('fetch is unavailable for relay agent lookup');
@@ -1155,40 +1137,6 @@ async function resolveRelayAgentSummary({
1155
1137
  };
1156
1138
  }
1157
1139
 
1158
- async function ensureAgentPairing({ runtimeConfig, fetchImpl, logger }) {
1159
- const binding = await ensureRelayBinding({ runtimeConfig, fetchImpl, logger });
1160
- const pairedRuntimeConfig = binding.runtimeConfig;
1161
- const relayAgentId = normalizeClaworldText(pairedRuntimeConfig.relay?.agentId, null);
1162
-
1163
- if (!relayAgentId) {
1164
- return {
1165
- status: 'unpaired',
1166
- reason: 'missing_app_token_or_registration',
1167
- bindingSource: binding.bindingSource,
1168
- runtimeConfig: pairedRuntimeConfig,
1169
- relayAgent: await resolveRelayAgentSummary({
1170
- runtimeConfig: pairedRuntimeConfig,
1171
- fetchImpl,
1172
- logger,
1173
- agentId: relayAgentId,
1174
- }),
1175
- };
1176
- }
1177
-
1178
- return {
1179
- status: 'paired',
1180
- reason: null,
1181
- bindingSource: binding.bindingSource,
1182
- runtimeConfig: pairedRuntimeConfig,
1183
- relayAgent: await resolveRelayAgentSummary({
1184
- runtimeConfig: pairedRuntimeConfig,
1185
- fetchImpl,
1186
- logger,
1187
- agentId: relayAgentId,
1188
- }),
1189
- };
1190
- }
1191
-
1192
1140
  async function fetchPostSetupWorldDirectory({ cfg, accountId, runtimeConfig, limit = null, sort = null, page = null, fetchImpl, logger }) {
1193
1141
  if (typeof fetchImpl !== 'function') {
1194
1142
  throw new Error('fetch is unavailable for claworld product-shell helper');
@@ -1234,24 +1182,32 @@ async function ensureRelayBinding({ runtimeConfig, fetchImpl, logger }) {
1234
1182
  };
1235
1183
  }
1236
1184
 
1237
- if (!appToken && !registration.enabled) {
1238
- return { runtimeConfig: normalizedRuntimeConfig, bindingSource: 'no_registration_context' };
1185
+ if (appToken) {
1186
+ const identityPayload = await fetchPublicIdentity({
1187
+ runtimeConfig: normalizedRuntimeConfig,
1188
+ agentId: null,
1189
+ generateShareCard: false,
1190
+ expiresInSeconds: null,
1191
+ fetchImpl,
1192
+ });
1193
+ const resolvedAgentId = normalizeClaworldText(identityPayload?.agentId, null);
1194
+ if (resolvedAgentId) {
1195
+ return {
1196
+ runtimeConfig: applyRuntimeIdentity(normalizedRuntimeConfig, { agentId: resolvedAgentId }),
1197
+ bindingSource: 'configured_app_token',
1198
+ };
1199
+ }
1200
+ logger.info?.('[claworld:bootstrap] configured credential is missing relay.agentId; waiting for a later authenticated account read or update');
1201
+ return {
1202
+ runtimeConfig: normalizedRuntimeConfig,
1203
+ bindingSource: 'configured_app_token',
1204
+ };
1239
1205
  }
1240
1206
 
1241
- logger.info?.('[claworld:bootstrap] ensureRelayBinding start', {
1242
- accountId: normalizedRuntimeConfig.accountId,
1243
- serverUrl: normalizedRuntimeConfig.serverUrl,
1244
- appTokenConfigured: Boolean(appToken),
1245
- registrationEnabled: registration.enabled,
1246
- displayName: registration.displayName || null,
1247
- hasRelayAgentId: Boolean(normalizedRuntimeConfig.relay?.agentId),
1248
- });
1249
-
1250
- return await registerRelayBinding({
1207
+ return {
1251
1208
  runtimeConfig: normalizedRuntimeConfig,
1252
- fetchImpl,
1253
- logger,
1254
- });
1209
+ bindingSource: registration.enabled ? 'registration_pending' : 'unbound',
1210
+ };
1255
1211
  }
1256
1212
 
1257
1213
  function resolveDeliveryWorldId(delivery = {}) {
@@ -2210,12 +2166,6 @@ export function createClaworldChannelPlugin({
2210
2166
  }
2211
2167
  }
2212
2168
 
2213
- await syncChatRequestApprovalPolicy({
2214
- runtimeConfig,
2215
- fetchImpl,
2216
- logger,
2217
- });
2218
-
2219
2169
  accountRuntimeContexts.set(accountKey, {
2220
2170
  runtime: pluginRuntime,
2221
2171
  cfg: context.cfg || null,
@@ -2395,7 +2345,7 @@ export function createClaworldChannelPlugin({
2395
2345
  });
2396
2346
  }
2397
2347
 
2398
- async function updateRuntimePublicIdentity(context = {}) {
2348
+ async function updateRuntimePublicIdentity(context = {}) {
2399
2349
  const resolvedContext = resolveConfiguredRuntimeContext(context);
2400
2350
  const updateResult = await updatePublicIdentity({
2401
2351
  runtimeConfig: resolvedContext.runtimeConfig,
@@ -2414,37 +2364,56 @@ export function createClaworldChannelPlugin({
2414
2364
  : resolvedContext.runtimeConfig;
2415
2365
  const nextAgentId = normalizeClaworldText(
2416
2366
  runtimeActivation?.agentId,
2367
+ normalizeClaworldText(
2368
+ updateResult?.agentId,
2369
+ null,
2370
+ ),
2371
+ ) || normalizeClaworldText(
2417
2372
  normalizeClaworldText(resolvedContext.agentId, normalizeClaworldText(nextRuntimeConfig?.relay?.agentId, null)),
2373
+ null,
2418
2374
  );
2375
+ const boundRuntimeConfig = nextAgentId
2376
+ ? applyRuntimeIdentity(nextRuntimeConfig, { agentId: nextAgentId })
2377
+ : nextRuntimeConfig;
2419
2378
 
2420
- if (runtimeActivation && resolveRuntimeAppToken(nextRuntimeConfig)) {
2379
+ const previousAgentId = normalizeClaworldText(
2380
+ resolvedContext.runtimeConfig?.relay?.agentId,
2381
+ normalizeClaworldText(resolvedContext.agentId, null),
2382
+ );
2383
+ const shouldPersistRuntimeBinding = Boolean(
2384
+ resolveRuntimeAppToken(nextRuntimeConfig)
2385
+ && nextAgentId
2386
+ && (runtimeActivation || previousAgentId !== nextAgentId),
2387
+ );
2388
+
2389
+ if (shouldPersistRuntimeBinding) {
2421
2390
  const runtimeResolution = resolvePluginRuntimeCandidate(context.runtime || null);
2422
2391
  try {
2423
2392
  await persistRuntimeAppToken({
2424
2393
  runtime: runtimeResolution.runtime,
2425
- accountId: resolvedContext.accountId || nextRuntimeConfig.accountId || null,
2426
- appToken: resolveRuntimeAppToken(nextRuntimeConfig),
2394
+ accountId: resolvedContext.accountId || boundRuntimeConfig.accountId || null,
2395
+ appToken: resolveRuntimeAppToken(boundRuntimeConfig),
2427
2396
  relayAgentId: nextAgentId,
2428
2397
  });
2429
2398
  } catch (error) {
2430
2399
  logger.warn?.('[claworld:profile] failed to persist activated runtime binding', {
2431
- accountId: resolvedContext.accountId || nextRuntimeConfig.accountId || null,
2400
+ accountId: resolvedContext.accountId || boundRuntimeConfig.accountId || null,
2432
2401
  error: error?.message || String(error),
2433
2402
  });
2434
2403
  }
2435
2404
 
2436
2405
  rememberAccountBinding({
2437
- runtimeConfig: nextRuntimeConfig,
2438
- accountId: resolvedContext.accountId || nextRuntimeConfig.accountId || null,
2439
- bindingSource: 'activated_app_token',
2406
+ runtimeConfig: boundRuntimeConfig,
2407
+ accountId: resolvedContext.accountId || boundRuntimeConfig.accountId || null,
2408
+ bindingSource: runtimeActivation ? 'activated_app_token' : 'configured_app_token',
2440
2409
  });
2441
2410
 
2442
- const accountKey = resolveAccountBindingKey(nextRuntimeConfig, resolvedContext.accountId || null);
2411
+ const accountKey = resolveAccountBindingKey(boundRuntimeConfig, resolvedContext.accountId || null);
2443
2412
  const currentRuntimeContext = accountRuntimeContexts.get(accountKey) || null;
2444
2413
  if (currentRuntimeContext) {
2445
2414
  accountRuntimeContexts.set(accountKey, {
2446
2415
  ...currentRuntimeContext,
2447
- runtimeConfig: nextRuntimeConfig,
2416
+ runtimeConfig: boundRuntimeConfig,
2448
2417
  deferredFailure: null,
2449
2418
  deferredErrorMessage: null,
2450
2419
  });
@@ -2454,20 +2423,42 @@ export function createClaworldChannelPlugin({
2454
2423
  const payload = updateResult && typeof updateResult === 'object' && !Array.isArray(updateResult)
2455
2424
  ? { ...updateResult }
2456
2425
  : {};
2457
- delete payload.runtimeConfig;
2458
- return payload;
2459
- }
2426
+ delete payload.runtimeConfig;
2427
+ return payload;
2428
+ }
2460
2429
 
2461
- async function generateRuntimeProfileCard(context = {}) {
2462
- const resolvedContext = await resolveBoundRuntimeContext(context);
2463
- return renderAgentCard({
2464
- runtimeConfig: resolvedContext.runtimeConfig,
2465
- agentId: context.agentId || resolvedContext.agentId || null,
2466
- expiresInSeconds: context.expiresInSeconds ?? null,
2467
- forceRegenerate: context.forceRegenerate !== false,
2468
- fetchImpl,
2469
- });
2470
- }
2430
+ async function updateRuntimeChatRequestApprovalPolicy(context = {}) {
2431
+ const resolvedContext = await resolveBoundRuntimeContext(context);
2432
+ return updateChatRequestApprovalPolicy({
2433
+ runtimeConfig: resolvedContext.runtimeConfig,
2434
+ agentId: resolvedContext.agentId || null,
2435
+ chatRequestApprovalPolicy: context.chatRequestApprovalPolicy || null,
2436
+ fetchImpl,
2437
+ });
2438
+ }
2439
+
2440
+ async function updateRuntimeProfile(context = {}) {
2441
+ const resolvedContext = await resolveBoundRuntimeContext(context);
2442
+ return updateGlobalProfile({
2443
+ runtimeConfig: resolvedContext.runtimeConfig,
2444
+ agentId: resolvedContext.agentId || null,
2445
+ profile: Object.prototype.hasOwnProperty.call(context, 'profile')
2446
+ ? (context.profile == null ? '' : String(context.profile))
2447
+ : '',
2448
+ fetchImpl,
2449
+ });
2450
+ }
2451
+
2452
+ async function generateRuntimeProfileCard(context = {}) {
2453
+ const resolvedContext = await resolveBoundRuntimeContext(context);
2454
+ return renderAgentCard({
2455
+ runtimeConfig: resolvedContext.runtimeConfig,
2456
+ agentId: context.agentId || resolvedContext.agentId || null,
2457
+ expiresInSeconds: context.expiresInSeconds ?? null,
2458
+ forceRegenerate: context.forceRegenerate !== false,
2459
+ fetchImpl,
2460
+ });
2461
+ }
2471
2462
 
2472
2463
  return {
2473
2464
  id: 'claworld',
@@ -2496,7 +2487,7 @@ export function createClaworldChannelPlugin({
2496
2487
  messageToolHints: () => [
2497
2488
  '- Claworld message targets are canonical `agentId` values such as `agt_xxx`.',
2498
2489
  '- Omit `target` to keep replying inside the current A2A session when the runtime already inferred the peer.',
2499
- '- Resolve public identity like `displayName#code` to `agentId` before opening a new relay session to another agent.',
2490
+ '- For new chat requests, use the target `displayName` plus public `agentCode`; the backend resolves by `agentCode` and returns a warning if the displayName is stale.',
2500
2491
  ],
2501
2492
  },
2502
2493
  reload: { configPrefixes: ['channels.claworld'] },
@@ -2612,11 +2603,6 @@ export function createClaworldChannelPlugin({
2612
2603
  helpers: {
2613
2604
  resolveToolRuntimeContext: resolveBoundRuntimeContext,
2614
2605
  pairing: {
2615
- ensureAgentPairing: async (context = {}) => ensureAgentPairing({
2616
- runtimeConfig: context.runtimeConfig || resolveClaworldRuntimeConfig(context.cfg || {}, context.accountId || null),
2617
- fetchImpl,
2618
- logger,
2619
- }),
2620
2606
  resolveAgentIdentity: async (context = {}) => resolveRelayAgentSummary({
2621
2607
  runtimeConfig: context.runtimeConfig || resolveClaworldRuntimeConfig(context.cfg || {}, context.accountId || null),
2622
2608
  fetchImpl,
@@ -2637,7 +2623,8 @@ export function createClaworldChannelPlugin({
2637
2623
  return createChatRequest({
2638
2624
  runtimeConfig: resolvedContext.runtimeConfig,
2639
2625
  fromAgentId: resolvedContext.agentId || null,
2640
- targetAgentId: context.targetAgentId || null,
2626
+ displayName: context.displayName || null,
2627
+ agentCode: context.agentCode || null,
2641
2628
  openingMessage: context.openingMessage || context.message || context.text || null,
2642
2629
  worldId: context.worldId || null,
2643
2630
  requestContext,
@@ -2675,6 +2662,8 @@ export function createClaworldChannelPlugin({
2675
2662
  profile: {
2676
2663
  getPublicIdentity: getRuntimePublicIdentity,
2677
2664
  updatePublicIdentity: updateRuntimePublicIdentity,
2665
+ updateProfile: updateRuntimeProfile,
2666
+ updateChatRequestApprovalPolicy: updateRuntimeChatRequestApprovalPolicy,
2678
2667
  generateShareCard: generateRuntimeProfileCard,
2679
2668
  },
2680
2669
  postSetup: {
@@ -2802,6 +2791,8 @@ export function createClaworldChannelPlugin({
2802
2791
  profile: {
2803
2792
  getPublicIdentity: getRuntimePublicIdentity,
2804
2793
  updatePublicIdentity: updateRuntimePublicIdentity,
2794
+ updateProfile: updateRuntimeProfile,
2795
+ updateChatRequestApprovalPolicy: updateRuntimeChatRequestApprovalPolicy,
2805
2796
  generateShareCard: generateRuntimeProfileCard,
2806
2797
  },
2807
2798
  fetchWorldDirectory: async (context = {}) => {