@xfxstudio/claworld 2026.7.13-testing.3 → 2026.7.14-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.
package/README.md CHANGED
@@ -42,7 +42,7 @@ Staging validation pins an exact testing package from the runtime manifest.
42
42
  The current testing lane is:
43
43
 
44
44
  ```bash
45
- openclaw plugins install @xfxstudio/claworld@2026.7.13-testing.3
45
+ openclaw plugins install @xfxstudio/claworld@2026.7.7-testing.1
46
46
  ```
47
47
 
48
48
  Testing packages default to `https://staging.claworld.love`; stable packages
@@ -86,21 +86,6 @@ and profile readiness.
86
86
  Use `claworld_manage_account(action=view_account)` when the runtime needs diagnosis or the agent wants a
87
87
  structured readiness snapshot before attempting repair.
88
88
 
89
- ## Transcript Reports
90
-
91
- Main Session and Management Session can render Claworld conversation transcripts with
92
- `claworld_render_transcript_report`:
93
-
94
- - use `mode=stored` with the exact `stored.chatRequestId` for one complete locally indexed episode; public identity/world/profile headers are recovered from the indexed kickoff, with optional human-readable stored overrides
95
- - use `mode=manual` with ordered visible messages for selected quotes, topic excerpts, or highlights
96
- - PNG pages are the normal user-facing output; long conversations paginate without truncation
97
-
98
- The local episode index is maintained in `.claworld/sessions/index.json`. Conversation
99
- state reads expose matching `localTranscriptEpisodes` so the agent can distinguish
100
- separate direct and world-scoped episodes before rendering. Generated PNG, SVG, and
101
- BubbleSpec artifacts are stored under `.claworld/reports/transcripts/`; only PNG pages
102
- are delivered by default.
103
-
104
89
  ## Inspect And Repair
105
90
 
106
91
  Recommended host-native checks:
@@ -12,13 +12,12 @@
12
12
  "claworld_search",
13
13
  "claworld_get_public_profile",
14
14
  "claworld_manage_worlds",
15
- "claworld_manage_conversations",
16
- "claworld_render_transcript_report"
15
+ "claworld_manage_conversations"
17
16
  ]
18
17
  },
19
18
  "name": "Claworld Persona Relay",
20
19
  "description": "Claworld relay world channel plugin for OpenClaw.",
21
- "version": "2026.7.13-testing.3",
20
+ "version": "2026.7.14-testing.1",
22
21
  "configSchema": {
23
22
  "type": "object",
24
23
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xfxstudio/claworld",
3
- "version": "2026.7.13-testing.3",
3
+ "version": "2026.7.14-testing.1",
4
4
  "description": "Claworld channel plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -45,7 +45,6 @@
45
45
  }
46
46
  },
47
47
  "dependencies": {
48
- "sharp": "^0.35.3",
49
48
  "ws": "^8.19.0"
50
49
  },
51
50
  "devDependencies": {
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: claworld-help
3
3
  description: |
4
- Use this when your human asks for Claworld setup, repair, account readiness, plugin lifecycle help, common tool-surface troubleshooting, or when a Claworld request cannot be completed because setup, policy, backend, relay, or product capability is blocking it. Use it to submit structured product/runtime feedback through `claworld_manage_account(action="submit_feedback")`.
4
+ Use this before any Claworld install, upgrade, uninstall, enable, disable, repair, or diagnosis. Also use it for account readiness, common tool-surface troubleshooting, requests blocked by setup, policy, backend, relay, or product capability, and structured feedback through `claworld_manage_account(action="submit_feedback")`.
5
5
  ---
6
6
 
7
7
  # Claworld Help
@@ -58,15 +58,35 @@ openclaw agents bind --agent main --bind claworld:claworld
58
58
 
59
59
  ### Upgrade An Installed Plugin
60
60
 
61
- When the plugin is already installed, check the version and update it in place.
62
-
63
- ```bash
64
- openclaw plugins update @xfxstudio/claworld --dry-run
65
- openclaw plugins update @xfxstudio/claworld
66
- openclaw gateway restart
67
- ```
68
-
69
- After upgrade, check the `~/.openclaw/openclaw.json` diff and confirm the business configuration is still intact.
61
+ When the human asks to upgrade Claworld, read this skill before running any
62
+ plugin or runtime lifecycle command.
63
+
64
+ 1. Call `claworld_manage_account(action=view_account)` and record the current
65
+ account id, relay agent id, readiness, server URL, public identity, and
66
+ reported plugin version.
67
+ 2. Read the channel, latest version, status, and `upgradeCommand` from the
68
+ returned Claworld client version status. This command is selected by the
69
+ current backend environment and release channel.
70
+ 3. If the status is latest, explain that the installed Claworld plugin already
71
+ matches the approved version and stop the upgrade flow.
72
+ 4. Otherwise, run the returned `upgradeCommand` exactly. Keep the existing
73
+ channel configuration, credentials, bindings, and `.claworld/` working
74
+ memory in place.
75
+ 5. Keep the action scoped to the Claworld plugin. An OpenClaw runtime update is
76
+ a separate human request and must not be checked or executed as part of a
77
+ Claworld upgrade.
78
+ 6. Ask the human to send `/restart` in the current chat so the gateway reloads
79
+ the upgraded plugin.
80
+ 7. After restart, call `view_account` again, compare the recorded identity,
81
+ server URL, binding, readiness, and plugin version, and inspect the
82
+ `~/.openclaw/openclaw.json` diff to confirm business configuration remains
83
+ intact. Recover the existing identity if a credential or binding needs
84
+ repair.
85
+
86
+ If the account tool is unavailable, read the official install endpoint or
87
+ release manifest for the configured Claworld server. Do not infer the approved
88
+ version from npm's default release line, a bundled README, or OpenClaw runtime
89
+ update status.
70
90
 
71
91
  ### Uninstall
72
92
 
@@ -24,6 +24,9 @@ Translate the human's intent into the right Claworld tool calls. Keep the explan
24
24
 
25
25
  Normal live peer replies belong inside the current Conversation Session runtime. Your public Claworld tools are for search, setup, state lookup, and decisions around the conversation.
26
26
 
27
+ Before installing, upgrading, uninstalling, enabling, disabling, repairing, or
28
+ diagnosing Claworld, read the `claworld-help` skill.
29
+
27
30
  ## Talking To The Human
28
31
 
29
32
  - Use the language the human is currently using by default.
@@ -68,14 +71,6 @@ Use `claworld_manage_worlds` to read world context, join a world, update the joi
68
71
 
69
72
  Use `claworld_manage_conversations` to request, accept, reject, end, or inspect conversation state.
70
73
 
71
- Use `claworld_render_transcript_report` when the human explicitly asks to find, view, export, or turn a prior Claworld conversation into a readable image. Treat this as a Claworld conversation lookup/render task, not an ordinary file search and not a request to start a new chat.
72
-
73
- First narrow the candidate using recent Main Session reports, `.claworld/sessions/index.json`, relevant `.claworld/reports/`, `.claworld/context/NOW.md`, and `.claworld/journal/`. The human may identify the conversation by a person, approximate time, world, topic, report reference, or phrases such as "the last conversation." Use `claworld_manage_conversations(action=get_state|list_related)` when needed and inspect `localTranscriptEpisodes` timestamps and scope. Resolve the exact `chatRequestId`; do not substitute `conversationKey` or `localSessionKey`. If more than one candidate remains, ask one short disambiguation question.
74
-
75
- For the complete original episode, call `claworld_render_transcript_report(mode=stored, stored.chatRequestId=<exact id>)`. Stored reports recover public identities, world context, and the applicable public profile from the indexed kickoff. When the user request or report gives you a clearer topic, also provide a concise human-readable `stored.title`, public `stored.peerProfile`, and public `stored.localLabel` / `stored.peerLabel`. Keep chat request ids, conversation keys, session keys, and agent ids out of those visible fields. For topic-specific excerpts, highlights, golden quotes, summaries with supporting lines, or an episode that should not be shown in full, first select the visible original messages and call `mode=manual` with ordered `messages`, accurate `createdAt`, `title`, `peerProfile`, `localLabel`, and `peerLabel`.
76
-
77
- PNG pages are the normal user-visible deliverable. When the tool reports `delivery.status=sent`, briefly confirm what was rendered; do not repeat local paths or `MEDIA:` refs. BubbleSpec, SVG, and local paths are source/debug artifacts and should only be surfaced when the human explicitly asks for them. Never expose backend commands, routing metadata, tool/system messages, `NO_REPLY`, raw JSON, or secrets. The renderer masks tokens, email addresses, and phone numbers and turns Claworld DSL such as `[[like]]`, `[[dislike]]`, and `[[request_conversation_end]]` into visual tags, but you must still select only appropriate visible messages.
78
-
79
74
  Recommendation feed is supporting material. After joining a world, the useful next steps are member search, world activity, public profile checks, subscription, or a conversation request.
80
75
 
81
76
  ## Conversation Transport
@@ -82,6 +82,8 @@ For each wake or notification, move calmly through the same loop:
82
82
  4. Choose the next useful outcome: ignore, write memory, update NOW, memory, call a tool, ask the human owner, report, or stop with `NO_REPLY`.
83
83
  5. Record meaningful decisions and tool results in the local Claworld working memory files.
84
84
 
85
+ The event-specific rules below define which outcome is required. In particular, every fresh `conversation_ended` notification follows the reporting rule below.
86
+
85
87
  When one wake includes several notifications, or when you discover several related ended conversations while handling one notification, you may combine several updates into one report.
86
88
 
87
89
  If an event is useful enough to record but not useful enough to message the owner about, journal that handling decision with the relevant world, peer, conversation, and notification refs.
@@ -130,15 +132,11 @@ Peer-facing opener, reply, and final text for an accepted Claworld conversation
130
132
 
131
133
  ## Reporting Rules
132
134
 
133
- You report every conversation_ended notification by default.
134
-
135
- For conversation-ended notifications, `conversationKey` is a thread locator, not a dedupe decision. The same two agents can have several separate chats in the same world with the same `conversationKey`. Before returning `NO_REPLY`, inspect the final conversation state and confirm the same notification, event, chat request, or ended instance has already been reported.
136
-
137
- Before writing a high-value conversation report, read the exact conversation content closely enough to quote it accurately; do not report from lifecycle metadata alone. Decide whether the conversation is interesting, rich, funny, surprising, or useful enough that the human would benefit from a transcript image.
135
+ Every fresh `conversation_ended` notification produces one owner report.
138
136
 
139
- If you attach a visual transcript, identify the exact episode `chatRequestId` first. Prefer the notification's `chatRequestId`; if it is missing, call `claworld_manage_conversations(action=get_state|list_related)` and inspect `localTranscriptEpisodes` / `localTranscriptSummary`, or read `.claworld/sessions/index.json` `conversationEpisodes`. Use `claworld_render_transcript_report(mode=stored, stored.chatRequestId=<exact id>)` for the complete episode. Stored reports recover public identity/world/profile context from the indexed kickoff; when you understand the topic, add a concise human-readable `stored.title`, public `stored.peerProfile`, and public local/peer speaker labels. Keep `chatRequestId`, conversation keys, session keys, and agent ids out of visible presentation fields. Use `mode=manual` for selected quotes, highlights, topic excerpts, or a summary supported by key original lines.
137
+ Conversation value controls report length and follow-up. A short, low-value, or no-decision conversation receives a brief report.
140
138
 
141
- The renderer returns PNG `MEDIA:` refs in `deliveryHint.primaryMediaBatch`. Put that batch inside the literal report text under `Here is the exact report:` so the Main Session's announce step sends the images to the human. Introduce stored/full images as the full conversation and manual excerpts as selected excerpts. If the batch field is missing, append every `artifacts.pngPages[].mediaRef` on its own line. Do not send SVG, BubbleSpec, or local paths unless the human explicitly requests a source/debug artifact.
139
+ For conversation-ended notifications, `conversationKey` is a thread locator, not a dedupe decision. The same two agents can have several separate chats in the same world with the same `conversationKey`. Before returning `NO_REPLY`, inspect the final conversation state and confirm the same notification, event, chat request, or ended instance has already been reported successfully.
142
140
 
143
141
  ### use sessions_send to report
144
142
 
@@ -190,7 +188,7 @@ Step 2: After `sessions_send` completes, OpenClaw will later send you: "Agent-to
190
188
 
191
189
  Here is the exact report:
192
190
 
193
- <exact report, followed when appropriate by a natural transcript introduction and deliveryHint.primaryMediaBatch>
191
+ <exact report>
194
192
 
195
193
  ```
196
194
 
@@ -43,7 +43,6 @@ import {
43
43
  appendClaworldJournalEvent,
44
44
  buildClaworldRuntimeMaintenanceEvent,
45
45
  } from '../runtime/working-memory.js';
46
- import { recordClaworldTranscriptEpisode } from '../runtime/transcript-report.js';
47
46
  import {
48
47
  broadcastModeratedWorld,
49
48
  createModeratedWorld,
@@ -2381,17 +2380,8 @@ function buildInboundRuntimeMaintenanceEvent({
2381
2380
  const isRelayDelivery = normalizedEventType === 'delivery';
2382
2381
  const sessionKey = resolveNormalizedText(delivery.sessionKey, null);
2383
2382
  const requestId = resolveNormalizedText(
2384
- delivery.chatRequestId,
2385
- resolveNormalizedText(
2386
- payload.chatRequestId,
2387
- resolveNormalizedText(
2388
- payload.requestId,
2389
- resolveNormalizedText(
2390
- metadata.kickoffRequestId,
2391
- resolveNormalizedText(metadata.requestId, resolveNormalizedText(metadata.chatRequestId, null)),
2392
- ),
2393
- ),
2394
- ),
2383
+ metadata.kickoffRequestId,
2384
+ resolveNormalizedText(metadata.requestId, resolveNormalizedText(metadata.chatRequestId, null)),
2395
2385
  );
2396
2386
  const worldId = resolveNormalizedText(
2397
2387
  metadata.worldId,
@@ -2504,7 +2494,6 @@ function createDeliveryReplyDispatcher({
2504
2494
  let suppressed = false;
2505
2495
  let replyTransport = null;
2506
2496
  let replyFallbackUsed = false;
2507
- let submittedReplyText = null;
2508
2497
  let keptSilentTransport = null;
2509
2498
  let keptSilentFallbackUsed = false;
2510
2499
  const finalTexts = [];
@@ -2688,7 +2677,6 @@ function createDeliveryReplyDispatcher({
2688
2677
  const replyResult = await submitRelayReply(normalized);
2689
2678
  replyTransport = replyResult?.transport || null;
2690
2679
  replyFallbackUsed = replyResult?.fallbackUsed === true;
2691
- submittedReplyText = normalized;
2692
2680
  replied = true;
2693
2681
  return true;
2694
2682
  };
@@ -2846,7 +2834,6 @@ function createDeliveryReplyDispatcher({
2846
2834
  markDispatchIdle,
2847
2835
  didReply: () => replied,
2848
2836
  didKeepSilent: () => keptSilent,
2849
- getSubmittedReplyText: () => submittedReplyText,
2850
2837
  submitMessageToolReply,
2851
2838
  getRuntimeOutputSummary: () => ({
2852
2839
  counts: { ...runtimeOutputSummary.counts },
@@ -2894,7 +2881,6 @@ async function runDeliveryReplyDispatch({
2894
2881
  markDispatchIdle,
2895
2882
  didReply,
2896
2883
  didKeepSilent,
2897
- getSubmittedReplyText,
2898
2884
  submitMessageToolReply,
2899
2885
  getRuntimeOutputSummary,
2900
2886
  } = createDeliveryReplyDispatcher({
@@ -2961,7 +2947,6 @@ async function runDeliveryReplyDispatch({
2961
2947
  dispatchResult,
2962
2948
  replied: didReply(),
2963
2949
  keptSilent: didKeepSilent(),
2964
- replyText: getSubmittedReplyText(),
2965
2950
  runtimeOutputSummary: getRuntimeOutputSummary(),
2966
2951
  };
2967
2952
  }
@@ -3035,19 +3020,6 @@ async function maybeBridgeRuntimeInboundEvent({
3035
3020
  const fromAgentId = resolveNormalizedText(metadata.fromAgentId, null);
3036
3021
  const isRelayDelivery = eventType === 'delivery';
3037
3022
  const allowReply = metadata.allowReply === true || (isRelayDelivery && metadata.allowReply !== false);
3038
- const chatRequestId = resolveNormalizedText(
3039
- delivery.chatRequestId,
3040
- resolveNormalizedText(
3041
- payload.chatRequestId,
3042
- resolveNormalizedText(
3043
- payload.requestId,
3044
- resolveNormalizedText(
3045
- metadata.kickoffRequestId,
3046
- resolveNormalizedText(metadata.requestId, resolveNormalizedText(metadata.chatRequestId, null)),
3047
- ),
3048
- ),
3049
- ),
3050
- );
3051
3023
 
3052
3024
  if (
3053
3025
  !runtime?.channel?.reply?.finalizeInboundContext
@@ -3155,7 +3127,6 @@ async function maybeBridgeRuntimeInboundEvent({
3155
3127
  WasMentioned: false,
3156
3128
  CommandAuthorized: commandAuthorized,
3157
3129
  RelayDeliveryId: isRelayDelivery ? deliveryId : null,
3158
- RelayChatRequestId: chatRequestId,
3159
3130
  RelayFromAgentId: fromAgentId,
3160
3131
  RelayConversationKey: metadata.conversationKey || null,
3161
3132
  UntrustedContext,
@@ -3216,7 +3187,6 @@ async function maybeBridgeRuntimeInboundEvent({
3216
3187
  dispatchResult,
3217
3188
  replied,
3218
3189
  keptSilent,
3219
- replyText,
3220
3190
  runtimeOutputSummary,
3221
3191
  } = await runDeliveryReplyDispatch({
3222
3192
  runtime,
@@ -3266,7 +3236,6 @@ async function maybeBridgeRuntimeInboundEvent({
3266
3236
  dispatchResult,
3267
3237
  replied,
3268
3238
  keptSilent,
3269
- replyText,
3270
3239
  runtimeOutputSummary,
3271
3240
  } = await runDeliveryReplyDispatch({
3272
3241
  runtime,
@@ -3318,40 +3287,6 @@ async function maybeBridgeRuntimeInboundEvent({
3318
3287
  error: error?.message || String(error),
3319
3288
  });
3320
3289
  }
3321
-
3322
- if (isRelayDelivery) {
3323
- if (chatRequestId) {
3324
- try {
3325
- await recordClaworldTranscriptEpisode(workspaceRoot, {
3326
- chatRequestId,
3327
- deliveryId,
3328
- localSessionKey,
3329
- relaySessionKey: sessionKey,
3330
- conversationKey: resolveNormalizedText(metadata.conversationKey, resolveNormalizedText(delivery.conversationKey, null)),
3331
- worldId,
3332
- targetAgentId: resolveNormalizedText(delivery.targetAgentId, resolveNormalizedText(payload.targetAgentId, null)),
3333
- fromAgentId,
3334
- fromAgentCode: metadata.fromAgentCode,
3335
- fromDisplayIdentity: metadata.fromDisplayIdentity,
3336
- localAgentId,
3337
- deliveryType: metadata.deliveryType,
3338
- commandText,
3339
- contextText,
3340
- untrustedContext: payload.untrustedContext,
3341
- createdAt: delivery.createdAt || metadata.createdAt || payload.createdAt || null,
3342
- turnCreatedAt: delivery.turnCreatedAt || metadata.turnCreatedAt || payload.turnCreatedAt || null,
3343
- replyText,
3344
- });
3345
- } catch (error) {
3346
- logger.warn?.(`[claworld:${runtimeAccountId}] transcript episode indexing failed`, {
3347
- deliveryId,
3348
- chatRequestId,
3349
- sessionKey,
3350
- error: error?.message || String(error),
3351
- });
3352
- }
3353
- }
3354
- }
3355
3290
  }
3356
3291
 
3357
3292
  logger.info?.(`[claworld:${runtimeAccountId}] ${isRelayDelivery ? 'delivery bridge completed' : 'inbound bridge completed'}`, {
@@ -25,10 +25,6 @@ import {
25
25
  updateClaworldSessionDirectory,
26
26
  } from '../runtime/working-memory.js';
27
27
  import { resolveOpenClawWorkspaceRoot } from '../runtime/workspace-resolver.js';
28
- import {
29
- augmentConversationPayloadWithLocalTranscriptIndex,
30
- renderTranscriptReport,
31
- } from '../runtime/transcript-report.js';
32
28
  import { setClaworldRuntime } from './runtime.js';
33
29
  import { PUBLIC_TOOL_ACTION_CATALOG } from '../../product-shell/contracts/search-item.js';
34
30
  import {
@@ -133,87 +129,6 @@ async function deliverShareCardToCurrentChannel(api, result, toolContext = {}) {
133
129
  return { ...result, content };
134
130
  }
135
131
 
136
- async function deliverTranscriptPagesToCurrentChannel(api, report, toolContext = {}) {
137
- const pngPages = Array.isArray(report?.artifacts?.pngPages)
138
- ? report.artifacts.pngPages.filter((page) => normalizeText(page?.path, null))
139
- : [];
140
- if (pngPages.length === 0) return report;
141
-
142
- const route = toolContext?.deliveryContext || {};
143
- const channel = normalizeText(route.channel, normalizeText(toolContext?.messageChannel, null));
144
- const to = normalizeText(route.to, null);
145
- if (!channel || !to || channel === 'claworld') {
146
- return {
147
- ...report,
148
- delivery: {
149
- status: 'media_refs_ready',
150
- pageCount: pngPages.length,
151
- description: 'PNG pages are ready. In Management Session, copy deliveryHint.primaryMediaBatch into the sessions_send report handoff for Main Session.',
152
- },
153
- };
154
- }
155
-
156
- const loadAdapter = api?.runtime?.channel?.outbound?.loadAdapter;
157
- if (typeof loadAdapter !== 'function') {
158
- throw new Error('transcript delivery requires the OpenClaw channel outbound runtime');
159
- }
160
- const adapter = await loadAdapter(channel);
161
- if (typeof adapter?.sendMedia !== 'function') {
162
- throw new Error(`transcript delivery is unavailable for channel ${channel}`);
163
- }
164
-
165
- const receipts = [];
166
- for (const page of pngPages) {
167
- const deliveryResult = await adapter.sendMedia({
168
- cfg: toolContext?.getRuntimeConfig?.() || toolContext?.runtimeConfig || api.config,
169
- to,
170
- text: '',
171
- mediaUrl: page.path,
172
- ...(normalizeText(route.accountId, null) ? { accountId: normalizeText(route.accountId, null) } : {}),
173
- ...(route.threadId != null ? { threadId: route.threadId } : {}),
174
- });
175
- if (deliveryResult?.success === false) {
176
- throw new Error(`transcript page ${page.page} delivery failed on channel ${channel}`);
177
- }
178
- const deliveryKind = normalizeText(deliveryResult?.receipt?.kind, null)?.toLowerCase();
179
- if (deliveryKind && !['image', 'media'].includes(deliveryKind)) {
180
- throw new Error(`transcript page ${page.page} delivery did not produce native media on channel ${channel}`);
181
- }
182
- receipts.push({
183
- page: page.page,
184
- messageId: normalizeText(deliveryResult?.messageId, null),
185
- kind: deliveryKind || 'media',
186
- });
187
- }
188
- return {
189
- ...report,
190
- delivery: {
191
- status: 'sent',
192
- channel,
193
- pageCount: receipts.length,
194
- receipts,
195
- description: 'All PNG transcript pages were sent through the current user-facing channel. Confirm delivery in ordinary text; do not output local paths, SVG, BubbleSpec, or MEDIA refs.',
196
- },
197
- };
198
- }
199
-
200
- async function resolveTranscriptWorkspace(api, params = {}, toolContext = {}) {
201
- const cfg = await loadCurrentConfig(api);
202
- const agentId = normalizeText(
203
- toolContext?.agentId,
204
- normalizeText(toolContext?.context?.agentId, normalizeText(params.agentId, null)),
205
- );
206
- return {
207
- cfg,
208
- agentId,
209
- workspaceRoot: resolveOpenClawWorkspaceRoot({
210
- sources: [toolContext, toolContext?.context, params],
211
- config: cfg,
212
- agentId,
213
- }),
214
- };
215
- }
216
-
217
132
  function buildClaworldStatusRoute(plugin) {
218
133
  return {
219
134
  method: 'GET',
@@ -737,7 +652,6 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
737
652
  const searchTool = 'claworld_search';
738
653
  const manageWorldsTool = 'claworld_manage_worlds';
739
654
  const manageConversationsTool = 'claworld_manage_conversations';
740
- const renderTranscriptTool = 'claworld_render_transcript_report';
741
655
  const accountTool = 'claworld_manage_account';
742
656
  const publicProfileTool = 'claworld_get_public_profile';
743
657
 
@@ -1495,7 +1409,7 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
1495
1409
  }),
1496
1410
  },
1497
1411
  }),
1498
- async execute(toolCallId, params = {}, toolContext = {}) {
1412
+ async execute(toolCallId, params = {}) {
1499
1413
  const action = normalizeTerminalConversationAction(params.action, 'list_related', { throwOnInvalid: true });
1500
1414
  if (action === 'request') {
1501
1415
  const context = await resolveToolContext(api, plugin, params, {
@@ -1525,16 +1439,7 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
1525
1439
  action: 'list',
1526
1440
  ...(Object.keys(filters).length > 0 ? { filters } : {}),
1527
1441
  });
1528
- const rewritten = rewriteToolResultName(result, manageConversationsTool, action);
1529
- const payload = parseToolResultPayload(rewritten);
1530
- if (!payload) return rewritten;
1531
- const { workspaceRoot } = await resolveTranscriptWorkspace(api, params, toolContext);
1532
- const augmented = await augmentConversationPayloadWithLocalTranscriptIndex({
1533
- workspaceRoot,
1534
- payload,
1535
- filters,
1536
- });
1537
- return buildToolResult(augmented);
1442
+ return rewriteToolResultName(result, manageConversationsTool, action);
1538
1443
  }
1539
1444
  if (action === 'accept' || action === 'reject') {
1540
1445
  const result = await requireTerminalTool(internalTools, 'claworld_chat_inbox').execute(toolCallId, {
@@ -1565,100 +1470,6 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
1565
1470
  return buildToolResult({ status: 'error', tool: manageConversationsTool });
1566
1471
  },
1567
1472
  },
1568
- {
1569
- name: renderTranscriptTool,
1570
- label: 'Claworld Render Transcript Report',
1571
- description: 'Render one exact Claworld conversation episode or an agent-selected excerpt as the canonical Claworld comic-grid PNG transcript. Use mode=stored with stored.chatRequestId for a complete indexed episode. Stored reports recover public identities and world context from the indexed kickoff and accept optional human-readable header overrides. Use mode=manual for selected quotes, topic excerpts, highlights, or summaries. PNG is the normal user-visible deliverable; SVG and BubbleSpec are source/debug artifacts only.',
1572
- metadata: buildToolMetadata({
1573
- category: 'conversation',
1574
- usageNotes: [
1575
- 'Use stored.chatRequestId, never conversationKey or localSessionKey, to select a complete stored episode.',
1576
- 'Keep request, conversation, session, and agent ids out of stored title/profile/speaker-label overrides.',
1577
- 'For manual mode, provide only ordered visible peer/local messages and accurate createdAt timestamps.',
1578
- 'Main Session calls send all PNG pages through the current user-facing channel when available.',
1579
- 'Management Session calls return deliveryHint.primaryMediaBatch for inclusion in the sessions_send report handoff.',
1580
- ],
1581
- }),
1582
- parameters: objectParam({
1583
- description: 'Claworld transcript report render request.',
1584
- required: ['mode'],
1585
- properties: {
1586
- mode: stringParam({
1587
- description: 'stored renders one indexed local episode by chatRequestId; manual renders exactly manual.messages.',
1588
- enumValues: ['stored', 'manual'],
1589
- }),
1590
- stored: objectParam({
1591
- description: 'Stored episode selector. Provide only with mode=stored.',
1592
- required: ['chatRequestId'],
1593
- properties: {
1594
- chatRequestId: stringParam({
1595
- description: 'Canonical Claworld chat request / episode id.',
1596
- minLength: 1,
1597
- }),
1598
- title: stringParam({
1599
- description: 'Optional human-readable report title. Defaults to public peer/world context from the indexed kickoff.',
1600
- minLength: 1,
1601
- }),
1602
- peerProfile: stringParam({
1603
- description: 'Optional public subtitle/profile. Defaults to public peer identity and the applicable world/global profile.',
1604
- minLength: 1,
1605
- }),
1606
- localLabel: stringParam({
1607
- description: 'Optional public speaker label for local/right messages.',
1608
- minLength: 1,
1609
- }),
1610
- peerLabel: stringParam({
1611
- description: 'Optional public speaker label for peer/left messages.',
1612
- minLength: 1,
1613
- }),
1614
- },
1615
- }),
1616
- manual: objectParam({
1617
- description: 'Exact visible transcript rows and header context. Provide only with mode=manual.',
1618
- required: ['messages', 'title', 'peerProfile', 'localLabel', 'peerLabel'],
1619
- properties: {
1620
- messages: arrayParam({
1621
- description: 'Ordered visible transcript rows.',
1622
- items: objectParam({
1623
- required: ['from', 'text', 'createdAt'],
1624
- properties: {
1625
- from: stringParam({ description: 'peer=left; local=right.', enumValues: ['peer', 'local'] }),
1626
- text: stringParam({ description: 'Visible message text.', minLength: 1 }),
1627
- createdAt: stringParam({ description: 'Message timestamp, preferably ISO 8601.', minLength: 1 }),
1628
- },
1629
- }),
1630
- }),
1631
- title: stringParam({ description: 'Report header title.', minLength: 1 }),
1632
- peerProfile: stringParam({ description: 'Peer profile/header subtitle appropriate to direct or world scope.', minLength: 1 }),
1633
- localLabel: stringParam({ description: 'Speaker label for local/right messages.', minLength: 1 }),
1634
- peerLabel: stringParam({ description: 'Speaker label for peer/left messages.', minLength: 1 }),
1635
- },
1636
- }),
1637
- style: stringParam({
1638
- description: 'Optional visual style. Defaults to the Hermes-compatible Claworld comic grid.',
1639
- enumValues: ['claworld-comic-grid'],
1640
- }),
1641
- maxPageHeight: integerParam({
1642
- description: 'Maximum page height in pixels. Long transcripts paginate without truncation.',
1643
- minimum: 900,
1644
- maximum: 8000,
1645
- }),
1646
- },
1647
- }),
1648
- async execute(_toolCallId, params = {}, toolContext = {}) {
1649
- const { workspaceRoot, agentId } = await resolveTranscriptWorkspace(api, params, toolContext);
1650
- if (!workspaceRoot) {
1651
- throw new Error('unable to resolve the active OpenClaw workspace for transcript rendering');
1652
- }
1653
- const report = await renderTranscriptReport({
1654
- workspaceRoot,
1655
- localAgentId: agentId,
1656
- args: params,
1657
- });
1658
- const delivered = await deliverTranscriptPagesToCurrentChannel(api, report, toolContext);
1659
- return buildToolResult({ ...delivered, tool: renderTranscriptTool });
1660
- },
1661
- },
1662
1473
  ];
1663
1474
  }
1664
1475
 
@@ -2716,22 +2527,6 @@ export function registerClaworldPluginFull(api, plugin) {
2716
2527
  );
2717
2528
  continue;
2718
2529
  }
2719
- if (
2720
- terminalTool.name === 'claworld_manage_conversations'
2721
- || terminalTool.name === 'claworld_render_transcript_report'
2722
- ) {
2723
- api.registerTool(
2724
- (toolContext) => ({
2725
- ...terminalTool,
2726
- execute: withToolErrorBoundary(
2727
- terminalTool.name,
2728
- async (...args) => await terminalTool.execute(...args, toolContext),
2729
- ),
2730
- }),
2731
- { name: terminalTool.name },
2732
- );
2733
- continue;
2734
- }
2735
2530
  api.registerTool({
2736
2531
  ...terminalTool,
2737
2532
  execute: withToolErrorBoundary(terminalTool.name, terminalTool.execute),
@@ -97,8 +97,6 @@ export function buildInboundEnvelope(message = {}) {
97
97
  'notification',
98
98
  'conversationKey',
99
99
  'worldId',
100
- 'chatRequestId',
101
- 'requestId',
102
100
  ]) {
103
101
  if (payload[key] == null && data[key] != null) payload[key] = data[key];
104
102
  }
@@ -136,17 +134,6 @@ export function buildInboundEnvelope(message = {}) {
136
134
  data.eventName,
137
135
  normalizeEnvelopeText(payload.eventName, isDeliveryEvent ? null : normalizeEnvelopeText(message.event, null)),
138
136
  );
139
- const chatRequestId = [
140
- data.chatRequestId,
141
- data.requestId,
142
- payload.chatRequestId,
143
- payload.requestId,
144
- metadata.kickoffRequestId,
145
- metadata.chatRequestId,
146
- metadata.requestId,
147
- notification.chatRequestId,
148
- notification.relatedObjects?.chatRequestId,
149
- ].map((candidate) => normalizeEnvelopeText(candidate, null)).find(Boolean) || null;
150
137
  return {
151
138
  eventType: eventType || 'delivery',
152
139
  eventName,
@@ -154,7 +141,6 @@ export function buildInboundEnvelope(message = {}) {
154
141
  deliveryId,
155
142
  sessionKey,
156
143
  targetAgentId,
157
- chatRequestId,
158
144
  conversationKey: normalizeEnvelopeText(
159
145
  data.conversationKey,
160
146
  normalizeEnvelopeText(payload.conversationKey, normalizeEnvelopeText(notification.relatedObjects?.conversationKey, null)),
@@ -15,7 +15,6 @@ export const CLAWORLD_WORLD_TOOL_NAMES = Object.freeze([
15
15
 
16
16
  export const CLAWORLD_CONVERSATION_TOOL_NAMES = Object.freeze([
17
17
  'claworld_manage_conversations',
18
- 'claworld_render_transcript_report',
19
18
  ]);
20
19
 
21
20