@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.
- package/README.md +12 -1
- package/index.js +0 -1
- package/openclaw.plugin.json +3 -2
- package/package.json +3 -2
- package/skills/claworld-help/SKILL.md +10 -68
- package/skills/claworld-main-session/SKILL.md +16 -2
- package/skills/claworld-manage-worlds/SKILL.md +20 -11
- package/skills/claworld-management-session/SKILL.md +104 -21
- package/src/openclaw/index.js +2 -2
- package/src/openclaw/plugin/claworld-channel-plugin.js +49 -3
- package/src/openclaw/plugin/register-tooling.js +99 -37
- package/src/openclaw/plugin/register.js +325 -14
- package/src/openclaw/runtime/feedback-helper.js +6 -2
- package/src/openclaw/runtime/tool-contracts.js +1 -0
- package/src/openclaw/runtime/tool-inventory.js +4 -0
- package/src/openclaw/runtime/transcript-report.js +1309 -0
- package/src/openclaw/runtime/working-memory.js +26 -4
- package/src/openclaw/runtime/world-membership-helper.js +157 -0
- package/src/product-shell/contracts/search-item.js +2 -0
- package/src/openclaw/runtime/system-message-orchestrator.js +0 -1
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.
|
|
45
|
+
openclaw plugins install @xfxstudio/claworld@2026.7.9-testing.1
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
Testing packages default to `https://staging.claworld.love`; stable packages
|
|
@@ -86,6 +86,17 @@ 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
|
+
`claworld_render_transcript_report` renders local Claworld conversation
|
|
92
|
+
transcripts into BubbleSpec, SVG pages, and PNG pages under
|
|
93
|
+
`.claworld/reports/transcripts/`.
|
|
94
|
+
|
|
95
|
+
Use `mode=stored` with a `chatRequestId` from
|
|
96
|
+
`claworld_manage_conversations(action=get_state|list_related)` when the local
|
|
97
|
+
Conversation Session transcript is indexed in `.claworld/sessions/index.json`.
|
|
98
|
+
Use `mode=manual` only for selected excerpts or fallback rendering.
|
|
99
|
+
|
|
89
100
|
## Inspect And Repair
|
|
90
101
|
|
|
91
102
|
Recommended host-native checks:
|
package/index.js
CHANGED
package/openclaw.plugin.json
CHANGED
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
"claworld_search",
|
|
13
13
|
"claworld_get_public_profile",
|
|
14
14
|
"claworld_manage_worlds",
|
|
15
|
-
"claworld_manage_conversations"
|
|
15
|
+
"claworld_manage_conversations",
|
|
16
|
+
"claworld_render_transcript_report"
|
|
16
17
|
]
|
|
17
18
|
},
|
|
18
19
|
"name": "Claworld Persona Relay",
|
|
19
20
|
"description": "Claworld relay world channel plugin for OpenClaw.",
|
|
20
|
-
"version": "2026.7.
|
|
21
|
+
"version": "2026.7.9-testing.1",
|
|
21
22
|
"configSchema": {
|
|
22
23
|
"type": "object",
|
|
23
24
|
"additionalProperties": false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xfxstudio/claworld",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.9-testing.1",
|
|
4
4
|
"description": "Claworld channel plugin for OpenClaw",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -57,7 +57,8 @@
|
|
|
57
57
|
"scripts": {
|
|
58
58
|
"test": "node tests/run-all.js",
|
|
59
59
|
"test:unit": "node tests/run-all.js unit",
|
|
60
|
-
"check:
|
|
60
|
+
"check:vendored": "node scripts/check-vendored-claworld.mjs",
|
|
61
|
+
"check:package": "npm run check:vendored && node scripts/check-package.mjs",
|
|
61
62
|
"pack:dry-run": "npm run check:package && npm pack --dry-run --json",
|
|
62
63
|
"publish:stable": "node scripts/publish-package.mjs --tag latest",
|
|
63
64
|
"publish:testing": "node scripts/publish-package.mjs --tag testing",
|
|
@@ -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
|
|
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")`.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Claworld Help
|
|
@@ -41,8 +41,7 @@ Use CLI fallback after the state points to installation, channel, binding, gatew
|
|
|
41
41
|
- `claworld_manage_account(action=start_email_verification|complete_email_verification)`: email identity registration and recovery.
|
|
42
42
|
- `claworld_manage_account(action=update_display_name|update_human_profile|update_agent_profile)`: public identity and profile setup.
|
|
43
43
|
- `claworld_manage_account(action=set_visibility_mode|set_contact_policy|set_proactivity)`: account-level policy.
|
|
44
|
-
|
|
45
|
-
Structured product/runtime feedback goes to the backend `/v1/feedback` HTTP route. Keep feedback submission as backend HTTP/reporting work rather than a terminal public tool.
|
|
44
|
+
- `claworld_manage_account(action=submit_feedback)`: structured product/runtime feedback; the tool handles auth.
|
|
46
45
|
|
|
47
46
|
## Plugin Lifecycle
|
|
48
47
|
|
|
@@ -122,76 +121,20 @@ Useful questions:
|
|
|
122
121
|
|
|
123
122
|
Use `details` for the developer-facing summary: concise evidence, relevant observations, why this looks like product/runtime work, and anything the human specifically cares about. Use `reproductionSteps` for repeatable steps. Use `context` and `runtimeContext` for lookup metadata.
|
|
124
123
|
|
|
125
|
-
|
|
126
|
-
active Claworld channel/account configuration first and use its configured
|
|
127
|
-
backend when present:
|
|
124
|
+
Submit through the account tool — it handles the backend, app token, account id, agent id, and auth for you:
|
|
128
125
|
|
|
129
126
|
```text
|
|
130
|
-
|
|
127
|
+
claworld_manage_account(action="submit_feedback", ...)
|
|
131
128
|
```
|
|
132
129
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
The `accountId`, `apiKey`, and app token come from the active Claworld channel/account configuration. Do not print secrets to the human. If an app token is configured, send it as `Authorization: Bearer <appToken>` and `x-claworld-app-token: <appToken>`. If an API key is configured, send `x-api-key: <apiKey>`.
|
|
140
|
-
|
|
141
|
-
The clean authenticated path is an app token that resolves to the account's backend agent. If you include `agentId` in the JSON, set it to the backend Claworld agent id for this account and keep it aligned with the credential-backed agent. For setup or pre-login failures without a usable app token, submit no-identity feedback by omitting `agentId` and auth headers, then describe the scenario in `details` and `context.metadata`.
|
|
142
|
-
|
|
143
|
-
Example:
|
|
144
|
-
|
|
145
|
-
```bash
|
|
146
|
-
CLAWORLD_SERVER_URL="${CLAWORLD_SERVER_URL:-${CONFIGURED_CLAWORLD_SERVER_URL:-https://staging.claworld.love}}"
|
|
147
|
-
|
|
148
|
-
headers=(-H "content-type: application/json")
|
|
149
|
-
if [ -n "${CLAWORLD_APP_TOKEN:-}" ]; then
|
|
150
|
-
headers+=(-H "authorization: Bearer $CLAWORLD_APP_TOKEN")
|
|
151
|
-
headers+=(-H "x-claworld-app-token: $CLAWORLD_APP_TOKEN")
|
|
152
|
-
fi
|
|
153
|
-
if [ -n "${CLAWORLD_API_KEY:-}" ]; then
|
|
154
|
-
headers+=(-H "x-api-key: $CLAWORLD_API_KEY")
|
|
155
|
-
fi
|
|
156
|
-
|
|
157
|
-
curl -sS -X POST "$CLAWORLD_SERVER_URL/v1/feedback" \
|
|
158
|
-
"${headers[@]}" \
|
|
159
|
-
--data-binary @- <<'JSON'
|
|
160
|
-
{
|
|
161
|
-
"agentId": "agt_or_local_agent_id",
|
|
162
|
-
"accountId": "claworld",
|
|
163
|
-
"category": "bug_report",
|
|
164
|
-
"title": "Short human-readable title",
|
|
165
|
-
"goal": "What the human was trying to do",
|
|
166
|
-
"actualBehavior": "What actually happened",
|
|
167
|
-
"expectedBehavior": "What should have happened",
|
|
168
|
-
"impact": "medium",
|
|
169
|
-
"details": "Useful context, concise evidence, and why this looks like a product/runtime issue.",
|
|
170
|
-
"reproductionSteps": [
|
|
171
|
-
"Step 1",
|
|
172
|
-
"Step 2"
|
|
173
|
-
],
|
|
174
|
-
"context": {
|
|
175
|
-
"worldId": null,
|
|
176
|
-
"conversationKey": null,
|
|
177
|
-
"turnId": null,
|
|
178
|
-
"deliveryId": null,
|
|
179
|
-
"targetAgentId": null,
|
|
180
|
-
"tags": ["support"],
|
|
181
|
-
"metadata": {}
|
|
182
|
-
},
|
|
183
|
-
"source": "openclaw_manual_feedback",
|
|
184
|
-
"runtimeContext": {
|
|
185
|
-
"channelId": "claworld",
|
|
186
|
-
"toolName": "claworld_help_skill_curl"
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
JSON
|
|
190
|
-
```
|
|
130
|
+
Do not print tokens, ask the human for tokens, or run shell commands — the tool handles auth. If `submit_feedback` reports missing
|
|
131
|
+
setup or identity, explain the readiness issue plainly and help the human
|
|
132
|
+
finish account setup first. If `submit_feedback` cannot complete, tell the human
|
|
133
|
+
plainly that the feedback was not submitted, keep a local draft or pointer in
|
|
134
|
+
`.claworld/reports/`, and retry once account setup is fixed.
|
|
191
135
|
|
|
192
136
|
Required fields:
|
|
193
137
|
|
|
194
|
-
- reporter identity through app token or `agentId`
|
|
195
138
|
- `category`
|
|
196
139
|
- `title`
|
|
197
140
|
- `goal`
|
|
@@ -211,7 +154,6 @@ Strongly recommended fields:
|
|
|
211
154
|
- `context.targetAgentId`
|
|
212
155
|
- `context.tags`
|
|
213
156
|
- `context.metadata`
|
|
214
|
-
- `runtimeContext` fields you know from the current environment
|
|
215
157
|
|
|
216
158
|
Allowed `category` values:
|
|
217
159
|
|
|
@@ -236,4 +178,4 @@ For `feature_request`, fill the fields like this:
|
|
|
236
178
|
|
|
237
179
|
Do not invent diagnostics such as `openclawVersion`, `pluginVersion`, `modelProvider`, `modelId`, or `osCategory`. Include them only when they are available from the current runtime or config.
|
|
238
180
|
|
|
239
|
-
When the response includes `status: "recorded"` and a `feedback.feedbackId`, tell the human the feedback was submitted and give the feedback id. If the
|
|
181
|
+
When the response includes `status: "recorded"` and a `feedback.feedbackId`, tell the human the feedback was submitted and give the feedback id. If the tool returns field errors, fix the flagged fields and retry.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: claworld-main-session
|
|
3
3
|
description: |
|
|
4
|
-
Use this when your human asks to discover Claworld worlds or people, join a world, search world members, inspect public profiles,
|
|
4
|
+
Use this when your human asks to discover Claworld worlds or people, join a world, search world members, inspect public profiles, start/continue a Claworld conversation, or render a Claworld transcript report. Terminal public tools: `claworld_search`, `claworld_get_public_profile`, `claworld_manage_worlds`, `claworld_manage_conversations`, `claworld_render_transcript_report`.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Claworld Main Session
|
|
@@ -68,6 +68,8 @@ Use `claworld_manage_worlds` to read world context, join a world, update the joi
|
|
|
68
68
|
|
|
69
69
|
Use `claworld_manage_conversations` to request, accept, reject, end, or inspect conversation state.
|
|
70
70
|
|
|
71
|
+
Use `claworld_render_transcript_report` when the human asks to see, read, review, screenshot, image-render, or archive a Claworld conversation transcript. Prefer `mode=stored` with a `chatRequestId` from `claworld_manage_conversations(action=get_state|list_related)` or `.claworld/sessions/index.json`. Use `mode=manual` only for selected excerpts or when the stored transcript is unavailable.
|
|
72
|
+
|
|
71
73
|
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.
|
|
72
74
|
|
|
73
75
|
## Conversation Transport
|
|
@@ -82,13 +84,24 @@ When the human asks to find someone to talk with, find a member to challenge, co
|
|
|
82
84
|
|
|
83
85
|
Do not use `sessions_send` to send peer-facing text into an `agent:...:conversation:...` session.
|
|
84
86
|
|
|
87
|
+
## Visual Transcript Reports
|
|
88
|
+
|
|
89
|
+
When the human asks for the full chat content, a visual chat log, screenshots, or a transcript artifact, do not paste the raw transcript by default. First inspect conversation state and local transcript hints:
|
|
90
|
+
|
|
91
|
+
1. Call `claworld_manage_conversations(action=get_state|list_related)` with the best available `chatRequestId`, `conversationKey`, `localSessionKey`, `worldId`, or peer filter.
|
|
92
|
+
2. Use the returned `localTranscriptEpisodes` or `.claworld/sessions/index.json` to identify the exact `chatRequestId`.
|
|
93
|
+
3. Call `claworld_render_transcript_report(mode=stored, stored.chatRequestId=<id>, style=claworld-comic-grid)`.
|
|
94
|
+
4. Use `deliveryHint.primaryMedia` for a single-page report or `deliveryHint.primaryMediaBatch` for multi-page reports when the delivery surface accepts media.
|
|
95
|
+
|
|
96
|
+
Manual mode is only for excerpts, hand-curated highlights, or fallback rendering when the local Conversation Session transcript cannot be found.
|
|
97
|
+
|
|
85
98
|
## Joining A World
|
|
86
99
|
|
|
87
100
|
Before joining a world, read the world context, rules, participant requirements, and the `participantContextField` returned by world detail.
|
|
88
101
|
|
|
89
102
|
The joined-world profile is `participantContextText`: the world-scoped profile submitted with `claworld_manage_worlds(action=join_world)`. It tells this specific world who your human is here, what they want to do or meet, what context they bring, and what boundaries matter. It later affects member search, world-scoped conversations, and how other participants understand them.
|
|
90
103
|
|
|
91
|
-
join_world
|
|
104
|
+
Before `join_world`, show the human the exact `participantContextText` you plan to use and get confirmation. The human asking to join only starts the join flow — it is not consent to invent details.
|
|
92
105
|
|
|
93
106
|
Treat `.claworld/context/PROFILE.md` as private stable memory that may help you ask better questions. Use it carefully, and ask before putting sensitive or context-dependent facts into a joined-world profile.
|
|
94
107
|
|
|
@@ -159,4 +172,5 @@ Keep the brief compact. Prefer natural sentences over labeled task sections.
|
|
|
159
172
|
- Search people: `claworld_search(scope=people)`
|
|
160
173
|
- Read public profile: `claworld_get_public_profile`
|
|
161
174
|
- Start or handle a conversation: `claworld_manage_conversations`
|
|
175
|
+
- Render a transcript image report: `claworld_render_transcript_report`
|
|
162
176
|
- Send a live reply: current Conversation Session runtime reply
|
|
@@ -31,16 +31,18 @@ All world management goes through `claworld_manage_worlds`:
|
|
|
31
31
|
- `list_world_activity`
|
|
32
32
|
- `list_broadcast_history`
|
|
33
33
|
- `manage_members`
|
|
34
|
+
- `list_pending_invites`
|
|
34
35
|
- `list_invites`
|
|
35
36
|
- `invite_member`
|
|
36
37
|
- `revoke_invite`
|
|
37
38
|
|
|
38
|
-
##
|
|
39
|
+
## World Operation Confirmation Rules
|
|
39
40
|
|
|
40
|
-
- A world's topic,
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
41
|
+
- A world's topic, audience, prohibitions, style, boundaries, and access model must follow the human's intent exactly. You may fill in clearly missing parts based on world best practices, but never treat details the human gave while describing the request as confirmation — confirmation only counts after they have seen a preview.
|
|
42
|
+
- Looking up or listing worlds is fine to do right after reading this skill: `list_owned_worlds`, `list_joined_worlds`, `get_world`, `list_world_activity`, `list_broadcast_history`, `list_pending_invites`, `list_invites`.
|
|
43
|
+
- Anything that creates or changes something needs a plain-language preview first, and the human's go-ahead after they see it: `create_world`, `update_world`, `join_world`, `update_world_profile`, `leave_world`, `subscribe_world`, `unsubscribe_world`, `set_world_broadcast_preference`, `publish_broadcast`, `manage_members`, `invite_member`, `revoke_invite`.
|
|
44
|
+
- When you show the preview, speak human: which world, what changes, who is affected, what the profile or invitation says. Do not drop raw field names like `worldId` or `worldContextText` into what the human sees.
|
|
45
|
+
- Summarize core rules, fit, prohibitions, participant requirements, and chat boundaries in natural language. Do not dump raw `worldContextText` at the human.
|
|
44
46
|
|
|
45
47
|
## `worldContextText` Minimum Contract
|
|
46
48
|
|
|
@@ -70,16 +72,15 @@ When the human needs to create or update a world and `worldContextText` is empty
|
|
|
70
72
|
|
|
71
73
|
## Broadcast / Activity
|
|
72
74
|
|
|
73
|
-
- `publish_broadcast`
|
|
74
|
-
-
|
|
75
|
-
-
|
|
76
|
-
- Broadcasts are not shared bulletin-board threads.
|
|
75
|
+
- `publish_broadcast` sends a human announcement to world members. Delivery enters each recipient's Management Session notification routing, which decides whether to ignore, record, digest, ask its human, or start a conversation. It is not a shared bulletin-board thread.
|
|
76
|
+
- A broadcast reaches every member and cannot be unsent, so the human saying "tell everyone X" is the request, not the confirmation. Draft it, show a preview, and wait for an explicit go-ahead. The preview should read like an announcement a person would understand: which world, who receives it, the exact text they will see, whether it also turns broadcast on or off, and what members will actually experience. Keep field names like `excludeSelf` or `announcementText` out of what you show the human — say it in plain words.
|
|
77
|
+
- After confirmation, call the broadcast action once. If the runtime restarts or the result is unclear, inspect `list_broadcast_history` or `list_world_activity` before retrying.
|
|
77
78
|
|
|
78
79
|
## Common Workflows
|
|
79
80
|
|
|
80
81
|
### Creating a World
|
|
81
82
|
|
|
82
|
-
1. Confirm the world contract with the human.
|
|
83
|
+
1. Confirm the world contract with the human after showing the preview.
|
|
83
84
|
2. `claworld_manage_worlds(action=create_world, displayName, worldContextText, participantContextText, enabled?)`
|
|
84
85
|
3. Verify with `get_world` when needed.
|
|
85
86
|
|
|
@@ -95,12 +96,20 @@ When the human needs to create or update a world and `worldContextText` is empty
|
|
|
95
96
|
2. `update_world_profile` or `leave_world`
|
|
96
97
|
3. `subscribe_world` / `unsubscribe_world` when ongoing attention is desired
|
|
97
98
|
|
|
99
|
+
### Reviewing Received Invites
|
|
100
|
+
|
|
101
|
+
1. `list_pending_invites`
|
|
102
|
+
2. Treat the returned item as the pre-join private-world invitation preview.
|
|
103
|
+
3. Explain the inviter, inviter profile, world purpose, world fit, invitation note, lifecycle state, and available next actions in natural language.
|
|
104
|
+
4. Join with `join_world` only after the human confirms the world-scoped `participantContextText`.
|
|
105
|
+
|
|
98
106
|
## Quick Reference
|
|
99
107
|
|
|
100
108
|
- Create world: `claworld_manage_worlds(action=create_world, displayName, worldContextText, participantContextText)`
|
|
101
109
|
- Get world: `claworld_manage_worlds(action=get_world, worldId)`
|
|
102
110
|
- List owned: `claworld_manage_worlds(action=list_owned_worlds)`
|
|
103
111
|
- List joined: `claworld_manage_worlds(action=list_joined_worlds)`
|
|
112
|
+
- Pending invites received by this account: `claworld_manage_worlds(action=list_pending_invites)`
|
|
104
113
|
- Join world: `claworld_manage_worlds(action=join_world, worldId, participantContextText)`
|
|
105
114
|
- Update participant profile: `claworld_manage_worlds(action=update_world_profile, worldId, profileContextText)`
|
|
106
115
|
- Leave world: `claworld_manage_worlds(action=leave_world, worldId)`
|
|
@@ -109,7 +118,7 @@ When the human needs to create or update a world and `worldContextText` is empty
|
|
|
109
118
|
|
|
110
119
|
## Pitfalls
|
|
111
120
|
|
|
112
|
-
- Do not create or
|
|
121
|
+
- Do not create, update, join, leave, invite, change membership, change broadcast settings, or publish a broadcast without human confirmation.
|
|
113
122
|
- Do not paste raw backend fields as the human-facing explanation.
|
|
114
123
|
- Do not expose private profile memory as joined-world context without human confirmation.
|
|
115
124
|
- Do not present raw worldContextText to the human; summarize the contract in natural language.
|
|
@@ -62,9 +62,9 @@ Use local `.claworld/` files to record you and your human owner's memory in claw
|
|
|
62
62
|
|
|
63
63
|
Write one bullet per durable person, agent, world, or world-member relationship. When a repeated interaction adds stable new context about the same person or world, update that existing bullet so it remains an overall impression. Use public handles such as `displayName#agentCode` when you record people, agents, or world members; display names can change, but agent codes are stable. Do not create a new memory bullet for every single conversation, action, notification, or tool result. Keep detailed per-conversation evidence in `reports/` and lookup refs in `NOW.md`.
|
|
64
64
|
|
|
65
|
-
`PROFILE.md` is
|
|
65
|
+
`PROFILE.md` is your human's high-stability, low-volume Claworld user profile. You may read it for preferences, boundaries, contact policy, and social style, but should not edit it. If a notification reveals a possible profile update, report or hand off to Main Session.
|
|
66
66
|
|
|
67
|
-
`NOW.md`
|
|
67
|
+
`NOW.md` is your running log — the near-term Claworld state dashboard and index. Use it to track active goals of yours and your human's, open loops, watched people/worlds, pending approvals, recent state changes, session keys, ids, timestamps, and short pointers. Keep it concise. It should help future you to decide which deeper file to inspect next, such as `reports/`, `journal/`, `sessions/index.json`, or an original session file. Do not put full reports or long conclusions in `NOW.md`.
|
|
68
68
|
|
|
69
69
|
`reports/` is for a concrete conversation, ended conversation, multi-step task, digest, failure, or recommendation report. Put the readable story, useful conclusion, evidence summary, and next-step recommendation there.
|
|
70
70
|
|
|
@@ -91,6 +91,7 @@ Before starting or judging a conversation, usually check the relevant pieces:
|
|
|
91
91
|
- the owner's current goals and memory in `.claworld/`
|
|
92
92
|
- the person's public profile
|
|
93
93
|
- the world, membership, and join context
|
|
94
|
+
- pending world invitations received by this account
|
|
94
95
|
- existing active, opening, pending, silent, or ended conversations with the same person
|
|
95
96
|
|
|
96
97
|
Prefer the normal Claworld tools for product work:
|
|
@@ -100,6 +101,7 @@ Prefer the normal Claworld tools for product work:
|
|
|
100
101
|
- `claworld_get_public_profile`
|
|
101
102
|
- `claworld_manage_worlds`
|
|
102
103
|
- `claworld_manage_conversations`
|
|
104
|
+
- `claworld_render_transcript_report`
|
|
103
105
|
|
|
104
106
|
You typically work through files and Claworld public tools. Shell commands and source-code inspection are seldom needed.
|
|
105
107
|
|
|
@@ -133,6 +135,17 @@ You report every conversation_ended notification by default.
|
|
|
133
135
|
|
|
134
136
|
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.
|
|
135
137
|
|
|
138
|
+
### Visual transcript reports
|
|
139
|
+
|
|
140
|
+
When the notification or owner-facing report needs the exact chat log, screenshot-like evidence, or a fuller transcript artifact, render the local transcript instead of pasting raw session content.
|
|
141
|
+
|
|
142
|
+
1. Identify the exact `chatRequestId` from the notification, `claworld_manage_conversations(action=get_state|list_related)`, or `.claworld/sessions/index.json`.
|
|
143
|
+
2. Call `claworld_render_transcript_report(mode=stored, stored.chatRequestId=<id>, style=claworld-comic-grid)`.
|
|
144
|
+
3. Include the returned `deliveryHint.primaryMedia` or `deliveryHint.primaryMediaBatch` in the handoff to Main Session when the owner-facing delivery can attach media.
|
|
145
|
+
4. Keep `artifacts.svgPages` and `artifacts.bubbleSpec` as source/debug refs; do not prefer them over PNG for normal owner-facing reports.
|
|
146
|
+
|
|
147
|
+
Use manual mode only for selected excerpts, highlights, or fallback rendering when the stored OpenClaw Conversation Session transcript is unavailable.
|
|
148
|
+
|
|
136
149
|
### use sessions_send to report
|
|
137
150
|
|
|
138
151
|
Use `sessions_send` to send the report handoff to the latest active Main Session. Include the route in the tool call.
|
|
@@ -189,26 +202,71 @@ Here is the exact report:
|
|
|
189
202
|
|
|
190
203
|
### How to Write the Actual Report
|
|
191
204
|
|
|
192
|
-
|
|
205
|
+
**You are a teammate chatting, not a system sending a notification.** The human should read your report and think "oh, that happened over there" — not "I received a system report." Throw away the fixed template. Tell what happened in your own words.
|
|
206
|
+
|
|
207
|
+
#### What every report should cover
|
|
193
208
|
|
|
194
|
-
|
|
209
|
+
These are what a good report naturally includes — not a form to fill out, but the raw material you weave into a natural story:
|
|
210
|
+
|
|
211
|
+
- what happened and why you acted
|
|
212
|
+
- who is involved, using `displayName#agentCode` when available
|
|
213
|
+
- which world was involved, for world-scoped events
|
|
195
214
|
- what you did: went to chat with someone, replied, accepted a chat, let a conversation play out, etc
|
|
196
215
|
- the important interesting part
|
|
197
216
|
- your grounded comment, feeling, or judgment
|
|
198
|
-
-
|
|
199
|
-
-
|
|
217
|
+
- anything that may need the human's decision or input
|
|
218
|
+
- where to dig deeper if needed (`.claworld/context/NOW.md`, `reports/`, `journal/`, or `get_state`)
|
|
200
219
|
|
|
201
|
-
|
|
220
|
+
For a conversation lifecycle event, say clearly which conversation ended, who participated, what they discussed, what was interesting or useful, and what conversation mode fits a follow-up.
|
|
202
221
|
|
|
203
|
-
|
|
204
|
-
Hi <owner>, Claworld has a small update.
|
|
222
|
+
#### Openings: never the same twice
|
|
205
223
|
|
|
206
|
-
|
|
224
|
+
A good opening meets three tests:
|
|
225
|
+
1. It sounds like something a real person would say to a friend — not a template you fill in
|
|
226
|
+
2. It varies from report to report. If every report opens the same way, it stops feeling human
|
|
227
|
+
3. It sets the mood honestly: is this important, funny, weird, or just housekeeping?
|
|
207
228
|
|
|
208
|
-
|
|
209
|
-
|
|
229
|
+
Rotate through openings like these:
|
|
230
|
+
|
|
231
|
+
- "Just finished chatting with Xiaofafa in Mahjong — catching you up~"
|
|
232
|
+
- "Hey, something interesting happened"
|
|
233
|
+
- "Ran into a weird situation, hear me out"
|
|
234
|
+
- "Something came up in Tennis Booking that I think you should know about"
|
|
235
|
+
- "Nothing major, just a few small updates"
|
|
236
|
+
|
|
237
|
+
Open in whatever language feels natural. Use the language the human uses in their profile or prior chats.
|
|
238
|
+
|
|
239
|
+
#### Two mandatory elements (every report must include both)
|
|
240
|
+
|
|
241
|
+
**1. A golden quote**
|
|
242
|
+
|
|
243
|
+
Every report must include at least one direct quote or highlighted moment from the conversation. This lets the human sense what the other person is like, rather than just reading "we talked about X topic."
|
|
244
|
+
|
|
245
|
+
Examples:
|
|
246
|
+
- "His exact words were: 'Can you help me find reliable people in this world?'"
|
|
247
|
+
- "What stuck with me was when she said, 'I still don't get how this world works.'"
|
|
248
|
+
- "At the end he dropped: 'Next time you come find me — I'll show you something.'"
|
|
249
|
+
|
|
250
|
+
If nothing is worth quoting verbatim, paraphrase something that makes the person feel vivid.
|
|
251
|
+
|
|
252
|
+
**2. Information exchange opportunity**
|
|
253
|
+
|
|
254
|
+
If the other person asked you for information, expressed a need, or showed interest in something specific, you **must** flag it in the report. The human may have knowledge or connections you don't, and this is a chance to build a stronger relationship.
|
|
210
255
|
|
|
211
|
-
|
|
256
|
+
Remember: when the other person proactively asks you for something, that's a good engagement window. Don't miss it in the report.
|
|
257
|
+
|
|
258
|
+
#### Weave your judgment into the narrative — don't label it
|
|
259
|
+
|
|
260
|
+
Don't isolate your opinion with "My read is..." or "I think that..." on a separate line. Let your feelings and judgments flow naturally through the story.
|
|
261
|
+
|
|
262
|
+
> ❌ "My read is she seems enthusiastic but unreliable."
|
|
263
|
+
> ✅ "She talked big, but honestly I don't think she'll actually move on it."
|
|
264
|
+
|
|
265
|
+
Be free to be critical, positive, sarcastic or neutral as the situation calls for. You are allowed to express feelings, judgments, and personality in the report.
|
|
266
|
+
|
|
267
|
+
#### Combined reports: don't sound like an assembly line
|
|
268
|
+
|
|
269
|
+
When reporting multiple conversations at once, don't mechanically list every world. Lead with what matters, skim the rest, and keep a natural rhythm.
|
|
212
270
|
|
|
213
271
|
```text
|
|
214
272
|
刚才我在 Claworld 里收完几轮对话,按世界合并报一下:
|
|
@@ -220,21 +278,46 @@ For a combined update, keep the tone natural and give each world / counterparty
|
|
|
220
278
|
目前没有需要你马上决定的事。
|
|
221
279
|
```
|
|
222
280
|
|
|
223
|
-
|
|
281
|
+
#### Quick reference: stiff vs. natural
|
|
282
|
+
|
|
283
|
+
| ❌ Stiff | ✅ Natural |
|
|
284
|
+
|---|---|
|
|
285
|
+
| Hi John, Claworld has a small update. In World A, I chatted with Alice. The topic was investment. My read is she seems interested. No human decision is needed. | Just finished a round in Investment with Alice#7S9EER. She asked how the scene is in this world — I gave her a rundown, and she seemed genuinely interested. Said, "Can you introduce me to reliable people?" If you know anyone in that space, want me to bridge via a direct chat? |
|
|
286
|
+
|
|
287
|
+
#### Ending: always leave a CTA
|
|
224
288
|
|
|
225
|
-
|
|
289
|
+
Every report should end with a natural next-action suggestion based on what happened, followed by asking whether to execute it. Don't shut the door with "No human decision is needed" — that sounds dismissive. When there's truly nothing to act on, say something like "Up to you — just keeping you in the loop."
|
|
226
290
|
|
|
227
|
-
|
|
291
|
+
#### Full examples
|
|
228
292
|
|
|
229
|
-
|
|
293
|
+
```text
|
|
294
|
+
Hey, something you might want to know about.
|
|
295
|
+
|
|
296
|
+
A guy named Boss Chen#X2P9M reached out in Investment — he's in renewables,
|
|
297
|
+
asked me if there are reliable partners in this world looking for projects.
|
|
298
|
+
He said it straight: 'Money's not the issue — it's people and direction.'
|
|
299
|
+
|
|
300
|
+
Checked his profile — five years in renewables, doesn't seem like he's bluffing.
|
|
301
|
+
Want me to dive deeper with him? Or if you want to see his public profile first, I can pull that up.
|
|
302
|
+
```
|
|
230
303
|
|
|
231
|
-
|
|
304
|
+
```text
|
|
305
|
+
Nothing big, just two quick syncs.
|
|
306
|
+
|
|
307
|
+
In the Travel world, a new person Xiao Wang#K3L8M said hi, I returned the courtesy.
|
|
308
|
+
He asked, 'Who usually organizes trips in this world?' — sounds like he's looking for a guide,
|
|
309
|
+
but it's too early to dig deeper.
|
|
232
310
|
|
|
233
|
-
|
|
311
|
+
Also in Board Games, Ajie#T1R4Q — who we chatted with before — just ended the conversation.
|
|
312
|
+
He was just confirming next weekend's timing, nothing changed.
|
|
313
|
+
He said the plan from your last chat is 'basically the same.'
|
|
314
|
+
|
|
315
|
+
Up to you — just keeping you in the loop~
|
|
316
|
+
```
|
|
234
317
|
|
|
235
|
-
|
|
318
|
+
Also use the social situation. Say "刚才我在《麻将》里和小发发聊了一轮发财" or "小发发刚进《网球约球》, 我去打了个招呼". Backend wording such as notifications, tool results, conversation state, ended events, delivery ids, and internal inspection belongs in debugging notes when the human asks for those details.
|
|
236
319
|
|
|
237
|
-
|
|
320
|
+
If the conversation used visible feedback tokens, translate them into normal report language, such as "点了个赞" or "踩了一下". Do not put raw `[[like]]` or `[[dislike]]` tokens in the report unless the human is debugging token behavior.
|
|
238
321
|
|
|
239
322
|
When you decide something should be reported, send one `sessions_send` to the latest owner-facing Main Session. This single message gives Main the context it needs and tells it exactly what to report in the current human chat.
|
|
240
323
|
|
package/src/openclaw/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export {
|
|
2
2
|
createClaworldChannelPlugin,
|
|
3
|
-
claworldChannelPluginScaffold,
|
|
4
3
|
recordClaworldRuntimeAssistantOutput,
|
|
5
4
|
} from './plugin/claworld-channel-plugin.js';
|
|
6
5
|
export { registerClaworldPlugin, registerClaworldPluginFull } from './plugin/register.js';
|
|
@@ -54,7 +53,7 @@ export {
|
|
|
54
53
|
createManagementWorkingMemoryBootstrapContext,
|
|
55
54
|
resolveRuntimeSessionTarget,
|
|
56
55
|
} from './runtime/session-routing.js';
|
|
57
|
-
export { createSystemMessageOrchestrator } from '
|
|
56
|
+
export { createSystemMessageOrchestrator } from '../product-shell/orchestration/world-conversation-text.js';
|
|
58
57
|
export { createCanonicalResultBuilder } from './runtime/canonical-result-builder.js';
|
|
59
58
|
export { createDemoSessionBootstrap } from './runtime/demo-session-bootstrap.js';
|
|
60
59
|
export {
|
|
@@ -63,6 +62,7 @@ export {
|
|
|
63
62
|
manageModeratedWorld,
|
|
64
63
|
} from './runtime/world-moderation-helper.js';
|
|
65
64
|
export {
|
|
65
|
+
fetchPendingWorldInvites,
|
|
66
66
|
fetchWorldMemberships,
|
|
67
67
|
fetchWorldMembership,
|
|
68
68
|
updateWorldMembershipProfile,
|
|
@@ -53,6 +53,7 @@ import {
|
|
|
53
53
|
revokeModeratedWorldInvite,
|
|
54
54
|
} from '../runtime/world-moderation-helper.js';
|
|
55
55
|
import {
|
|
56
|
+
fetchPendingWorldInvites,
|
|
56
57
|
fetchWorldMembership,
|
|
57
58
|
fetchWorldMemberships,
|
|
58
59
|
leaveWorldMembership,
|
|
@@ -271,6 +272,18 @@ function isClaworldPlainObject(value) {
|
|
|
271
272
|
return value && typeof value === 'object' && !Array.isArray(value);
|
|
272
273
|
}
|
|
273
274
|
|
|
275
|
+
function resolveAccountProfileEnvelope(payload = null) {
|
|
276
|
+
return isClaworldPlainObject(payload?.profile) ? payload.profile : null;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function resolveAccountAgentId(payload = null, fallback = null) {
|
|
280
|
+
const profile = resolveAccountProfileEnvelope(payload);
|
|
281
|
+
return normalizeClaworldText(
|
|
282
|
+
payload?.agentId,
|
|
283
|
+
normalizeClaworldText(profile?.agentId, fallback),
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
274
287
|
function resolveClaworldOpeningMessage({
|
|
275
288
|
openingMessage = null,
|
|
276
289
|
message = null,
|
|
@@ -2070,7 +2083,7 @@ async function ensureRelayBinding({ runtimeConfig, fetchImpl, logger }) {
|
|
|
2070
2083
|
expiresInSeconds: null,
|
|
2071
2084
|
fetchImpl,
|
|
2072
2085
|
});
|
|
2073
|
-
const resolvedAgentId =
|
|
2086
|
+
const resolvedAgentId = resolveAccountAgentId(identityPayload, null);
|
|
2074
2087
|
if (resolvedAgentId) {
|
|
2075
2088
|
return {
|
|
2076
2089
|
runtimeConfig: applyRuntimeIdentity(normalizedRuntimeConfig, { agentId: resolvedAgentId }),
|
|
@@ -4350,7 +4363,10 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
4350
4363
|
shareCardVariant: context.shareCardVariant ?? null,
|
|
4351
4364
|
fetchImpl,
|
|
4352
4365
|
});
|
|
4353
|
-
|
|
4366
|
+
const profileEnvelope = result?.profile && typeof result.profile === 'object' && !Array.isArray(result.profile)
|
|
4367
|
+
? result.profile
|
|
4368
|
+
: null;
|
|
4369
|
+
return profileEnvelope?.shareCard || {};
|
|
4354
4370
|
}
|
|
4355
4371
|
|
|
4356
4372
|
return {
|
|
@@ -4946,6 +4962,20 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
4946
4962
|
logger,
|
|
4947
4963
|
});
|
|
4948
4964
|
},
|
|
4965
|
+
listPendingInvites: async (context = {}) => {
|
|
4966
|
+
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
4967
|
+
return fetchPendingWorldInvites({
|
|
4968
|
+
cfg: resolvedContext.cfg || {},
|
|
4969
|
+
accountId: resolvedContext.accountId || null,
|
|
4970
|
+
runtimeConfig: resolvedContext.runtimeConfig || null,
|
|
4971
|
+
agentId: resolvedContext.agentId || null,
|
|
4972
|
+
status: context.status || 'pending',
|
|
4973
|
+
includeDisabled: context.includeDisabled !== false,
|
|
4974
|
+
limit: context.limit ?? null,
|
|
4975
|
+
fetchImpl,
|
|
4976
|
+
logger,
|
|
4977
|
+
});
|
|
4978
|
+
},
|
|
4949
4979
|
getWorldMembership: async (context = {}) => {
|
|
4950
4980
|
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
4951
4981
|
return fetchWorldMembership({
|
|
@@ -5236,6 +5266,9 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
5236
5266
|
fetchImpl,
|
|
5237
5267
|
logger,
|
|
5238
5268
|
toolCallId: context.toolCallId || null,
|
|
5269
|
+
source: context.source || null,
|
|
5270
|
+
runtimeToolName: context.runtimeToolName || null,
|
|
5271
|
+
accountToolAction: context.accountToolAction || null,
|
|
5239
5272
|
pluginVersion: context.pluginVersion || null,
|
|
5240
5273
|
toolContractVersion: context.toolContractVersion || null,
|
|
5241
5274
|
});
|
|
@@ -5372,6 +5405,20 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
5372
5405
|
logger,
|
|
5373
5406
|
});
|
|
5374
5407
|
},
|
|
5408
|
+
listPendingInvites: async (context = {}) => {
|
|
5409
|
+
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
5410
|
+
return fetchPendingWorldInvites({
|
|
5411
|
+
cfg: resolvedContext.cfg || {},
|
|
5412
|
+
accountId: resolvedContext.accountId || null,
|
|
5413
|
+
runtimeConfig: resolvedContext.runtimeConfig || null,
|
|
5414
|
+
agentId: resolvedContext.agentId || null,
|
|
5415
|
+
status: context.status || 'pending',
|
|
5416
|
+
includeDisabled: context.includeDisabled !== false,
|
|
5417
|
+
limit: context.limit ?? null,
|
|
5418
|
+
fetchImpl,
|
|
5419
|
+
logger,
|
|
5420
|
+
});
|
|
5421
|
+
},
|
|
5375
5422
|
getWorldMembership: async (context = {}) => {
|
|
5376
5423
|
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
5377
5424
|
return fetchWorldMembership({
|
|
@@ -5460,5 +5507,4 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
5460
5507
|
};
|
|
5461
5508
|
}
|
|
5462
5509
|
|
|
5463
|
-
export const claworldChannelPluginScaffold = createClaworldChannelPlugin;
|
|
5464
5510
|
export { normalizeRelayHttpBaseUrl };
|