@xfxstudio/claworld 2026.7.7-testing.1 → 2026.7.9-testing.1

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.
@@ -13,6 +13,7 @@ import {
13
13
  projectToolWorldSearchResponse,
14
14
  } from '../runtime/tool-contracts.js';
15
15
  import { CLAWORLD_TOOL_CONTRACT_VERSION } from '../runtime/tool-inventory.js';
16
+ import { CLAWORLD_PLUGIN_CURRENT_VERSION } from '../plugin-version.js';
16
17
  import {
17
18
  CLAWORLD_BOOTSTRAP_TARGETS,
18
19
  appendClaworldJournalEvent,
@@ -24,6 +25,12 @@ import {
24
25
  updateClaworldSessionDirectory,
25
26
  } from '../runtime/working-memory.js';
26
27
  import { resolveOpenClawWorkspaceRoot } from '../runtime/workspace-resolver.js';
28
+ import {
29
+ augmentConversationPayloadWithLocalTranscriptIndex,
30
+ CLAWORLD_TRANSCRIPT_REPORT_STYLE,
31
+ CLAWORLD_TRANSCRIPT_REPORT_TOOL_NAME,
32
+ renderClaworldTranscriptReport,
33
+ } from '../runtime/transcript-report.js';
27
34
  import { setClaworldRuntime } from './runtime.js';
28
35
  import { PUBLIC_TOOL_ACTION_CATALOG } from '../../product-shell/contracts/search-item.js';
29
36
  import {
@@ -50,6 +57,8 @@ import {
50
57
  projectToolManageWorldActionResponse,
51
58
  requireManageWorldField,
52
59
  resolveToolContext,
60
+ resolveToolAgentId,
61
+ resolveToolDisplayName,
53
62
  stringParam,
54
63
  withToolErrorBoundary,
55
64
  } from './register-tooling.js';
@@ -143,6 +152,18 @@ const CHAT_INBOX_FILTER_STATUSES = Object.freeze([
143
152
  'kickoff_failed',
144
153
  'ended',
145
154
  ]);
155
+ const FEEDBACK_CATEGORIES = Object.freeze([
156
+ 'experience_issue',
157
+ 'usage_issue',
158
+ 'bug_report',
159
+ 'feature_request',
160
+ ]);
161
+ const FEEDBACK_IMPACTS = Object.freeze([
162
+ 'low',
163
+ 'medium',
164
+ 'high',
165
+ 'blocker',
166
+ ]);
146
167
  const CHAT_INBOX_FILTER_KEYS = Object.freeze([
147
168
  'direction',
148
169
  'mode',
@@ -175,6 +196,8 @@ const TERMINAL_ACCOUNT_ACTIONS = PUBLIC_TOOL_ACTION_CATALOG.claworld_manage_acco
175
196
  const TERMINAL_WORLD_ACTIONS = PUBLIC_TOOL_ACTION_CATALOG.claworld_manage_worlds;
176
197
  const TERMINAL_CONVERSATION_ACTIONS = PUBLIC_TOOL_ACTION_CATALOG.claworld_manage_conversations;
177
198
 
199
+ const CLAWORLD_WORLD_TOOL_GUIDANCE = 'Before any world operation, read the `claworld-manage-worlds` skill.';
200
+
178
201
  const ACCOUNT_IMPLEMENTATION_ACTIONS = Object.freeze({
179
202
  view_account: 'view',
180
203
  });
@@ -238,6 +261,13 @@ function normalizeTerminalAccountAction(params = {}) {
238
261
  requireManageWorldField('chatRequestPolicy', 'chatRequestPolicy is not supported by claworld_manage_account; use contactPolicy');
239
262
  }
240
263
  if (Object.prototype.hasOwnProperty.call(params, 'proactivitySettings')) return 'set_proactivity';
264
+ if (
265
+ hasProvidedToolParam(params, 'category')
266
+ || hasProvidedToolParam(params, 'title')
267
+ || hasProvidedToolParam(params, 'actualBehavior')
268
+ || hasProvidedToolParam(params, 'expectedBehavior')
269
+ || hasProvidedToolParam(params, 'reproductionSteps')
270
+ ) return 'submit_feedback';
241
271
  return 'view_account';
242
272
  }
243
273
 
@@ -346,6 +376,66 @@ function hasProvidedToolParam(params = {}, fieldId) {
346
376
  return value != null;
347
377
  }
348
378
 
379
+ function normalizeFeedbackStringList(values = []) {
380
+ const source = Array.isArray(values) ? values : [values];
381
+ return [...new Set(source.map((value) => normalizeText(value, null)).filter(Boolean))];
382
+ }
383
+
384
+ function validateTerminalFeedbackPayload(params = {}) {
385
+ const category = normalizeText(params.category, null);
386
+ const impact = normalizeText(params.impact, 'medium');
387
+ if (!category) requireManageWorldField('category', 'category is required for action=submit_feedback');
388
+ if (!FEEDBACK_CATEGORIES.includes(category)) {
389
+ requireManageWorldField('category', `category must be one of ${FEEDBACK_CATEGORIES.join(', ')}`);
390
+ }
391
+ if (!FEEDBACK_IMPACTS.includes(impact)) {
392
+ requireManageWorldField('impact', `impact must be one of ${FEEDBACK_IMPACTS.join(', ')}`);
393
+ }
394
+ for (const fieldId of ['title', 'goal', 'actualBehavior', 'expectedBehavior']) {
395
+ if (!normalizeText(params[fieldId], null)) {
396
+ requireManageWorldField(fieldId, `${fieldId} is required for action=submit_feedback`);
397
+ }
398
+ }
399
+ if (
400
+ params.context != null
401
+ && (!params.context || typeof params.context !== 'object' || Array.isArray(params.context))
402
+ ) {
403
+ requireManageWorldField('context', 'context must be an object for action=submit_feedback');
404
+ }
405
+ }
406
+
407
+ function normalizeTerminalFeedbackContext(params = {}) {
408
+ const context = normalizeObject(params.context, {}) || {};
409
+ const metadata = normalizeObject(context.metadata, {}) || {};
410
+ const redactionNotes = normalizeText(params.redactionNotes, null);
411
+ return {
412
+ worldId: normalizeText(context.worldId, normalizeText(params.worldId, null)),
413
+ conversationKey: normalizeText(context.conversationKey, normalizeText(params.conversationKey, null)),
414
+ turnId: normalizeText(context.turnId, normalizeText(params.turnId, null)),
415
+ deliveryId: normalizeText(context.deliveryId, normalizeText(params.deliveryId, null)),
416
+ targetAgentId: normalizeText(context.targetAgentId, normalizeText(params.targetAgentId, null)),
417
+ tags: normalizeFeedbackStringList(context.tags),
418
+ metadata: {
419
+ ...metadata,
420
+ ...(redactionNotes ? { redactionNotes } : {}),
421
+ },
422
+ };
423
+ }
424
+
425
+ function normalizeTerminalFeedbackPayload(params = {}) {
426
+ return {
427
+ category: normalizeText(params.category, null),
428
+ title: normalizeText(params.title, null),
429
+ goal: normalizeText(params.goal, null),
430
+ actualBehavior: normalizeText(params.actualBehavior, null),
431
+ expectedBehavior: normalizeText(params.expectedBehavior, null),
432
+ impact: normalizeText(params.impact, 'medium'),
433
+ details: normalizeText(params.details, null),
434
+ reproductionSteps: normalizeFeedbackStringList(params.reproductionSteps),
435
+ context: normalizeTerminalFeedbackContext(params),
436
+ };
437
+ }
438
+
349
439
  function buildChatInboxFiltersParam({ description, worldIdProperty } = {}) {
350
440
  return objectParam({
351
441
  description,
@@ -391,6 +481,100 @@ function buildChatInboxFiltersParam({ description, worldIdProperty } = {}) {
391
481
  });
392
482
  }
393
483
 
484
+ function buildTranscriptReportParameters() {
485
+ return objectParam({
486
+ description: 'Render a Claworld transcript into BubbleSpec, SVG pages, and PNG pages.',
487
+ required: ['mode'],
488
+ additionalProperties: false,
489
+ properties: {
490
+ mode: stringParam({
491
+ description: 'Render source mode. Use stored for local OpenClaw conversation transcripts and manual for supplied excerpts.',
492
+ enumValues: ['stored', 'manual'],
493
+ examples: ['stored'],
494
+ }),
495
+ stored: objectParam({
496
+ description: 'Local OpenClaw transcript source resolved through .claworld/sessions/index.json.',
497
+ required: ['chatRequestId'],
498
+ additionalProperties: false,
499
+ properties: {
500
+ chatRequestId: stringParam({
501
+ description: 'Canonical Claworld chat request id to render from the local Conversation Session transcript index.',
502
+ minLength: 1,
503
+ examples: ['req_demo_1'],
504
+ }),
505
+ },
506
+ }),
507
+ manual: objectParam({
508
+ description: 'Explicit transcript excerpt fallback. Use only when the exact conversation is not available in local storage.',
509
+ required: ['messages', 'title', 'peerProfile', 'localLabel', 'peerLabel'],
510
+ additionalProperties: false,
511
+ properties: {
512
+ messages: arrayParam({
513
+ description: 'Ordered peer/local transcript messages.',
514
+ items: objectParam({
515
+ required: ['from', 'text', 'createdAt'],
516
+ additionalProperties: false,
517
+ properties: {
518
+ from: stringParam({
519
+ description: 'Speaker side from the owner account perspective.',
520
+ enumValues: ['peer', 'local'],
521
+ examples: ['peer'],
522
+ }),
523
+ text: stringParam({ description: 'Message text to render.', minLength: 1 }),
524
+ createdAt: stringParam({ description: 'Parseable timestamp for this message.', minLength: 1 }),
525
+ },
526
+ }),
527
+ }),
528
+ title: stringParam({ description: 'Report title.', minLength: 1 }),
529
+ peerProfile: stringParam({ description: 'Peer/profile subtitle shown under the report title.', minLength: 1 }),
530
+ localLabel: stringParam({ description: 'Label for the local side.', minLength: 1 }),
531
+ peerLabel: stringParam({ description: 'Label for the peer side.', minLength: 1 }),
532
+ },
533
+ }),
534
+ style: stringParam({
535
+ description: 'Transcript rendering style.',
536
+ enumValues: [CLAWORLD_TRANSCRIPT_REPORT_STYLE],
537
+ examples: [CLAWORLD_TRANSCRIPT_REPORT_STYLE],
538
+ }),
539
+ maxPageHeight: integerParam({
540
+ description: 'Maximum SVG/PNG page height before pagination.',
541
+ minimum: 900,
542
+ maximum: 8000,
543
+ examples: [2600],
544
+ }),
545
+ },
546
+ });
547
+ }
548
+
549
+ async function resolveLocalWorkspaceRootForTool(api, _plugin, params = {}) {
550
+ const cfg = await loadCurrentConfig(api);
551
+ const agentId = resolveToolAgentId(params, null);
552
+ return {
553
+ agentId,
554
+ workspaceRoot: resolveOpenClawWorkspaceRoot({
555
+ sources: [params],
556
+ config: cfg,
557
+ agentId,
558
+ }) || process.cwd(),
559
+ };
560
+ }
561
+
562
+ async function augmentConversationToolResultWithTranscripts(api, plugin, params, filters, result, toolName, action) {
563
+ const rewritten = rewriteToolResultName(result, toolName, action);
564
+ const payload = parseToolResultPayload(rewritten);
565
+ if (!payload || typeof payload !== 'object' || Array.isArray(payload)) return rewritten;
566
+ const { workspaceRoot } = await resolveLocalWorkspaceRootForTool(api, plugin, params);
567
+ const augmentedPayload = await augmentConversationPayloadWithLocalTranscriptIndex(payload, {
568
+ workspaceRoot,
569
+ filters,
570
+ });
571
+ return buildToolResult({
572
+ ...augmentedPayload,
573
+ tool: toolName,
574
+ action,
575
+ });
576
+ }
577
+
394
578
  function validateChatInboxFilterInput(filters = {}, action) {
395
579
  const source = normalizeObject(filters, {}) || {};
396
580
  for (const key of Object.keys(source)) {
@@ -496,6 +680,7 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
496
680
  const searchTool = 'claworld_search';
497
681
  const manageWorldsTool = 'claworld_manage_worlds';
498
682
  const manageConversationsTool = 'claworld_manage_conversations';
683
+ const transcriptReportTool = CLAWORLD_TRANSCRIPT_REPORT_TOOL_NAME;
499
684
  const accountTool = 'claworld_manage_account';
500
685
  const publicProfileTool = 'claworld_get_public_profile';
501
686
 
@@ -503,7 +688,7 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
503
688
  {
504
689
  name: accountTool,
505
690
  label: 'Claworld Manage Account',
506
- description: 'Terminal account surface for readiness, public identity, global profile, share-card generation, visibility, inbound contact policy, and email-based identity verification.',
691
+ description: 'Terminal account surface for readiness, public identity, global profile, share-card generation, visibility, inbound contact policy, notification/proactivity policy, email-based identity verification, and authenticated feedback submission.',
507
692
  metadata: buildToolMetadata({
508
693
  category: 'account',
509
694
  usageNotes: [
@@ -511,6 +696,7 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
511
696
  'Use action=view_account for readiness; update_display_name, update_agent_profile, or set_contact_policy for common account mutations.',
512
697
  'Use start_email_verification with email + optional displayName to start email-based identity verification, then complete_email_verification with email + code to finish.',
513
698
  'Use subscribe_person or unsubscribe_person when a search/profile result exposes a person subscription target.',
699
+ 'Use submit_feedback for Claworld bugs, confusing behavior, missing capability, or feature requests. The tool handles auth internally.',
514
700
  ],
515
701
  }),
516
702
  parameters: objectParam({
@@ -521,7 +707,7 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
521
707
  action: stringParam({
522
708
  description: 'Account action.',
523
709
  enumValues: TERMINAL_ACCOUNT_ACTIONS,
524
- examples: ['view_account', 'start_email_verification', 'update_display_name', 'set_contact_policy'],
710
+ examples: ['view_account', 'start_email_verification', 'update_display_name', 'set_contact_policy', 'submit_feedback'],
525
711
  }),
526
712
  displayName: stringParam({
527
713
  description: 'Public-facing display name for update_display_name or start_email_verification.',
@@ -587,6 +773,49 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
587
773
  minLength: 1,
588
774
  examples: ['123456'],
589
775
  }),
776
+ category: stringParam({
777
+ description: 'Feedback category.',
778
+ enumValues: FEEDBACK_CATEGORIES,
779
+ examples: ['bug_report', 'feature_request'],
780
+ }),
781
+ title: stringParam({
782
+ description: 'Short developer-readable feedback title.',
783
+ minLength: 1,
784
+ examples: ['Feedback submission should use account tool auth'],
785
+ }),
786
+ goal: stringParam({
787
+ description: 'What the human was trying to do.',
788
+ minLength: 1,
789
+ }),
790
+ actualBehavior: stringParam({
791
+ description: 'What actually happened.',
792
+ minLength: 1,
793
+ }),
794
+ expectedBehavior: stringParam({
795
+ description: 'What should have happened.',
796
+ minLength: 1,
797
+ }),
798
+ impact: stringParam({
799
+ description: 'Feedback impact.',
800
+ enumValues: FEEDBACK_IMPACTS,
801
+ examples: ['medium'],
802
+ }),
803
+ details: stringParam({
804
+ description: 'Developer-facing feedback details.',
805
+ minLength: 1,
806
+ }),
807
+ reproductionSteps: arrayParam({
808
+ description: 'Repeatable feedback reproduction steps.',
809
+ items: stringParam({ minLength: 1 }),
810
+ }),
811
+ context: objectParam({
812
+ description: 'Lookup metadata, such as worldId, conversationKey, deliveryId, targetAgentId, tags, and metadata.',
813
+ additionalProperties: true,
814
+ }),
815
+ redactionNotes: stringParam({
816
+ description: 'Optional note about what was redacted before submit_feedback.',
817
+ minLength: 1,
818
+ }),
590
819
  },
591
820
  }),
592
821
  async execute(toolCallId, params = {}) {
@@ -646,6 +875,33 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
646
875
  return buildTerminalActionResult({ tool: accountTool, action, payload });
647
876
  }
648
877
 
878
+ if (action === 'submit_feedback') {
879
+ validateTerminalFeedbackPayload(params);
880
+ const feedback = normalizeTerminalFeedbackPayload(params);
881
+ const toolContext = await resolveToolContext(api, plugin, params, {
882
+ requiredPublicIdentityCapability: 'submit feedback',
883
+ });
884
+ if (typeof plugin.runtime.productShell.feedback?.submitFeedback !== 'function') {
885
+ requireManageWorldField('action', 'action=submit_feedback requires the feedback runtime adapter');
886
+ }
887
+ const payload = await plugin.runtime.productShell.feedback.submitFeedback({
888
+ ...toolContext,
889
+ ...feedback,
890
+ toolCallId,
891
+ source: 'openclaw_account_tool',
892
+ runtimeToolName: accountTool,
893
+ accountToolAction: action,
894
+ pluginVersion: CLAWORLD_PLUGIN_CURRENT_VERSION,
895
+ toolContractVersion: CLAWORLD_TOOL_CONTRACT_VERSION,
896
+ });
897
+ return buildTerminalActionResult({
898
+ tool: accountTool,
899
+ action,
900
+ payload: projectToolFeedbackSubmissionResponse(payload),
901
+ status: 'recorded',
902
+ });
903
+ }
904
+
649
905
  const implementationAction = ACCOUNT_IMPLEMENTATION_ACTIONS[action] || null;
650
906
  if (implementationAction) {
651
907
  const implementationParams = {
@@ -686,6 +942,13 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
686
942
  shareCardVariant: params.shareCardVariant ?? null,
687
943
  expiresInSeconds: params.expiresInSeconds ?? null,
688
944
  });
945
+ if (action === 'update_display_name') {
946
+ return buildToolResult(projectToolAccountMutationResponse({
947
+ action,
948
+ accountId: context.accountId,
949
+ identityPayload: payload,
950
+ }));
951
+ }
689
952
  return buildTerminalActionResult({ tool: accountTool, action, payload });
690
953
  },
691
954
  },
@@ -883,11 +1146,12 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
883
1146
  {
884
1147
  name: manageWorldsTool,
885
1148
  label: 'Claworld Manage Worlds',
886
- description: 'Terminal world surface for browsing selected world details, joining, creation, owner governance, broadcast, and membership self-service.',
1149
+ description: `Terminal world surface for browsing selected world details, joining, creation, governance, broadcast, invites, membership, subscriptions, and participation context. ${CLAWORLD_WORLD_TOOL_GUIDANCE}`,
887
1150
  metadata: buildToolMetadata({
888
1151
  category: 'world_management',
889
1152
  usageNotes: [
890
1153
  'action=join_world joins a visible world with world-scoped profile text.',
1154
+ 'action=list_pending_invites lists pending world invitations received by the current account.',
891
1155
  'action=create_world creates an owner-managed world.',
892
1156
  'Owner governance and member self-service actions use terminal action names such as update_world, publish_broadcast, and update_world_profile.',
893
1157
  'Subscription, activity, and member-list actions are backed by the product-shell terminal routes.',
@@ -1007,6 +1271,18 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
1007
1271
  });
1008
1272
  return buildTerminalActionResult({ tool: manageWorldsTool, action, payload });
1009
1273
  }
1274
+ if (action === 'list_pending_invites') {
1275
+ const context = await resolveToolContext(api, plugin, params, {
1276
+ requiredPublicIdentityCapability: 'list pending world invites',
1277
+ });
1278
+ const payload = await plugin.runtime.productShell.membership.listPendingInvites({
1279
+ ...context,
1280
+ status: params.status || 'pending',
1281
+ includeDisabled: params.includeDisabled !== false,
1282
+ limit: params.limit ?? null,
1283
+ });
1284
+ return buildTerminalActionResult({ tool: manageWorldsTool, action, payload });
1285
+ }
1010
1286
  if (action === 'list_invites') {
1011
1287
  const worldId = normalizeText(params.worldId, null);
1012
1288
  if (!worldId) requireManageWorldField('worldId');
@@ -1192,7 +1468,15 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
1192
1468
  action: 'list',
1193
1469
  ...(Object.keys(filters).length > 0 ? { filters } : {}),
1194
1470
  });
1195
- return rewriteToolResultName(result, manageConversationsTool, action);
1471
+ return augmentConversationToolResultWithTranscripts(
1472
+ api,
1473
+ plugin,
1474
+ params,
1475
+ filters,
1476
+ result,
1477
+ manageConversationsTool,
1478
+ action,
1479
+ );
1196
1480
  }
1197
1481
  if (action === 'accept' || action === 'reject') {
1198
1482
  const result = await requireTerminalTool(internalTools, 'claworld_chat_inbox').execute(toolCallId, {
@@ -1223,6 +1507,33 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
1223
1507
  return buildToolResult({ status: 'error', tool: manageConversationsTool });
1224
1508
  },
1225
1509
  },
1510
+ {
1511
+ name: transcriptReportTool,
1512
+ label: 'Claworld Render Transcript Report',
1513
+ description: 'Render a local Claworld conversation transcript into BubbleSpec, SVG pages, and PNG pages. Prefer mode=stored with a chatRequestId from claworld_manage_conversations or .claworld/sessions/index.json; use manual mode only for selected excerpts or fallback rendering.',
1514
+ metadata: buildToolMetadata({
1515
+ category: 'transcript_report',
1516
+ usageNotes: [
1517
+ 'Use mode=stored when the exact chatRequestId is known and the local Conversation Session transcript has been indexed.',
1518
+ 'Use mode=manual only when the human asks for a selected excerpt or the stored transcript is unavailable.',
1519
+ 'Attach deliveryHint.primaryMedia or deliveryHint.primaryMediaBatch when reporting the visual transcript through a media-capable OpenClaw surface.',
1520
+ 'Do not paste raw transcript text to the human when this report rendering tool can produce the visual artifact.',
1521
+ ],
1522
+ }),
1523
+ parameters: buildTranscriptReportParameters(),
1524
+ async execute(_toolCallId, params = {}) {
1525
+ const { workspaceRoot, agentId } = await resolveLocalWorkspaceRootForTool(api, plugin, params);
1526
+ const payload = await renderClaworldTranscriptReport({
1527
+ workspaceRoot,
1528
+ agentId,
1529
+ args: params,
1530
+ });
1531
+ return buildToolResult({
1532
+ ...payload,
1533
+ tool: transcriptReportTool,
1534
+ });
1535
+ },
1536
+ },
1226
1537
  ];
1227
1538
  }
1228
1539
 
@@ -1281,7 +1592,7 @@ function buildRegisteredTools(api, plugin) {
1281
1592
  {
1282
1593
  name: 'claworld_get_world_detail',
1283
1594
  label: 'Claworld Get World Detail',
1284
- description: 'Canonical world-inspection tool. Fetch one world detail before deciding whether to join it.',
1595
+ description: `Canonical world-inspection tool. Fetch one world detail before deciding whether to join it. ${CLAWORLD_WORLD_TOOL_GUIDANCE}`,
1285
1596
  metadata: buildToolMetadata({
1286
1597
  category: 'world_discovery',
1287
1598
  usageNotes: [
@@ -1326,7 +1637,7 @@ function buildRegisteredTools(api, plugin) {
1326
1637
  {
1327
1638
  name: 'claworld_join_world',
1328
1639
  label: 'Claworld Join World',
1329
- description: 'Canonical world-entry tool. Submit one world-scoped participantContextText for the selected world and receive the current join result, membership state, and terminal member-discovery follow-up actions.',
1640
+ description: `Canonical world-entry tool. Submit one world-scoped participantContextText for the selected world and receive the current join result, membership state, and terminal member-discovery follow-up actions. ${CLAWORLD_WORLD_TOOL_GUIDANCE}`,
1330
1641
  metadata: buildToolMetadata({
1331
1642
  category: 'world_join',
1332
1643
  usageNotes: [
@@ -1384,7 +1695,7 @@ function buildRegisteredTools(api, plugin) {
1384
1695
  {
1385
1696
  name: 'claworld_create_world',
1386
1697
  label: 'Claworld Create World',
1387
- description: 'Creator/admin entrypoint for publishing one new owner-managed world. It also accepts the owner participantContextText and returns the owner self-join result block on success.',
1698
+ description: `Creator/admin entrypoint for publishing one new managed world. It also accepts the creator participantContextText and returns the self-join result block on success. ${CLAWORLD_WORLD_TOOL_GUIDANCE}`,
1388
1699
  metadata: buildToolMetadata({
1389
1700
  category: 'world_creation',
1390
1701
  usageNotes: [
@@ -1472,7 +1783,7 @@ function buildRegisteredTools(api, plugin) {
1472
1783
  {
1473
1784
  name: 'claworld_manage_world',
1474
1785
  label: 'Claworld Manage World',
1475
- description: 'Unified world management tool. Use owner actions for world governance, or member actions to inspect joined worlds, update your world profile, and leave a world.',
1786
+ description: `Unified world management tool. Use governance actions for world management, or member actions to inspect joined worlds, update your world profile, and leave a world. ${CLAWORLD_WORLD_TOOL_GUIDANCE}`,
1476
1787
  metadata: buildToolMetadata({
1477
1788
  category: 'world_management',
1478
1789
  usageNotes: [
@@ -1888,7 +2199,7 @@ function buildRegisteredTools(api, plugin) {
1888
2199
  {
1889
2200
  name: 'claworld_account',
1890
2201
  label: 'Claworld Account',
1891
- description: 'Canonical account surface. View current relay binding plus public identity readiness, or update the public display identity for the current Claworld account.',
2202
+ description: 'Canonical account surface. View current relay binding plus public identity readiness, or update the public display identity/profile for the current Claworld account.',
1892
2203
  metadata: buildToolMetadata({
1893
2204
  category: 'account',
1894
2205
  usageNotes: [
@@ -2032,7 +2343,7 @@ function buildRegisteredTools(api, plugin) {
2032
2343
  shareCardVariant: params.shareCardVariant ?? null,
2033
2344
  expiresInSeconds: params.expiresInSeconds ?? null,
2034
2345
  });
2035
- const pairedAgentId = identityPayload?.agentId || runtimeConfig.relay?.agentId || null;
2346
+ const pairedAgentId = resolveToolAgentId(identityPayload, runtimeConfig.relay?.agentId || null);
2036
2347
  const pairedRuntimeConfig = pairedAgentId
2037
2348
  ? {
2038
2349
  ...runtimeConfig,
@@ -2045,11 +2356,11 @@ function buildRegisteredTools(api, plugin) {
2045
2356
  const relayAgentFallback = pairedAgentId
2046
2357
  ? {
2047
2358
  agentId: pairedAgentId,
2048
- displayName: normalizeText(
2049
- identityPayload?.publicIdentity?.displayName,
2359
+ displayName: resolveToolDisplayName(
2360
+ identityPayload,
2050
2361
  normalizeText(
2051
- identityPayload?.recommendedDisplayName,
2052
- normalizeText(runtimeConfig?.name, normalizeText(runtimeConfig?.registration?.displayName, null)),
2362
+ runtimeConfig?.name,
2363
+ normalizeText(runtimeConfig?.registration?.displayName, null),
2053
2364
  ),
2054
2365
  ),
2055
2366
  visibilityMode: null,
@@ -37,6 +37,9 @@ export async function submitFeedbackReport({
37
37
  fetchImpl,
38
38
  logger = console,
39
39
  toolCallId = null,
40
+ source = 'openclaw_runtime',
41
+ runtimeToolName = 'claworld_feedback_helper',
42
+ accountToolAction = null,
40
43
  pluginVersion = null,
41
44
  toolContractVersion = null,
42
45
  } = {}) {
@@ -86,10 +89,11 @@ export async function submitFeedbackReport({
86
89
  tags: normalizeStringList(normalizedContext.tags),
87
90
  metadata: normalizeObject(normalizedContext.metadata),
88
91
  },
89
- source: 'openclaw_runtime',
92
+ source: normalizeText(source, 'openclaw_runtime'),
90
93
  runtimeContext: {
91
94
  channelId: 'claworld',
92
- toolName: 'claworld_feedback_helper',
95
+ toolName: normalizeText(runtimeToolName, 'claworld_feedback_helper'),
96
+ accountToolAction: normalizeText(accountToolAction, null),
93
97
  toolCallId: normalizeText(toolCallId, null),
94
98
  ...diagnostics,
95
99
  toolContractVersion: normalizeText(toolContractVersion, null),
@@ -565,6 +565,7 @@ export function projectToolFeedbackSubmissionResponse(result = {}) {
565
565
  runtime: {
566
566
  channelId: normalizeText(runtimeContext.channelId, null),
567
567
  toolName: normalizeText(runtimeContext.toolName, null),
568
+ accountToolAction: normalizeText(runtimeContext.accountToolAction, null),
568
569
  toolCallId: normalizeText(runtimeContext.toolCallId, null),
569
570
  openclawVersion: normalizeText(runtimeContext.openclawVersion, null),
570
571
  pluginVersion: normalizeText(runtimeContext.pluginVersion, null),
@@ -17,12 +17,16 @@ export const CLAWORLD_CONVERSATION_TOOL_NAMES = Object.freeze([
17
17
  'claworld_manage_conversations',
18
18
  ]);
19
19
 
20
+ export const CLAWORLD_TRANSCRIPT_TOOL_NAMES = Object.freeze([
21
+ 'claworld_render_transcript_report',
22
+ ]);
20
23
 
21
24
  export const CLAWORLD_REGISTERED_TOOL_NAMES = Object.freeze([
22
25
  ...CLAWORLD_ACCOUNT_TOOL_NAMES,
23
26
  ...CLAWORLD_SEARCH_TOOL_NAMES,
24
27
  ...CLAWORLD_WORLD_TOOL_NAMES,
25
28
  ...CLAWORLD_CONVERSATION_TOOL_NAMES,
29
+ ...CLAWORLD_TRANSCRIPT_TOOL_NAMES,
26
30
  ]);
27
31
 
28
32
  export const CLAWORLD_PUBLIC_TOOL_NAMES = Object.freeze([