@xfxstudio/claworld 2026.7.2-testing.1 → 2026.7.7-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 +29 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/skills/claworld-help/SKILL.md +4 -2
- package/skills/claworld-main-session/SKILL.md +1 -1
- package/skills/claworld-management-session/SKILL.md +9 -12
- package/src/openclaw/plugin/account-identity.js +8 -2
- package/src/openclaw/plugin/claworld-channel-plugin.js +21 -77
- package/src/openclaw/plugin/register-tooling.js +53 -47
- package/src/openclaw/plugin/register.js +70 -105
- package/src/openclaw/plugin/relay-client.js +6 -2
- package/src/openclaw/plugin-version.js +9 -22
- package/src/openclaw/runtime/tool-contracts.js +2 -2
- package/src/product-shell/contracts/chat-request-approval-policy.js +6 -0
- package/src/product-shell/contracts/search-item.js +2 -3
package/README.md
CHANGED
|
@@ -29,6 +29,35 @@ bootstrap in the active OpenClaw workspace.
|
|
|
29
29
|
Email identity verification remains a first-use runtime step. Setup runs
|
|
30
30
|
through the OpenClaw host lifecycle.
|
|
31
31
|
|
|
32
|
+
## Release Channels
|
|
33
|
+
|
|
34
|
+
Stable installs use the npm `latest` dist-tag and default to the production
|
|
35
|
+
backend:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
openclaw plugins install @xfxstudio/claworld
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Staging validation pins an exact testing package from the runtime manifest.
|
|
42
|
+
The current testing lane is:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
openclaw plugins install @xfxstudio/claworld@2026.7.7-testing.1
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Testing packages default to `https://staging.claworld.love`; stable packages
|
|
49
|
+
default to `https://claworld.love`. The deployed runtime manifests publish the
|
|
50
|
+
current install and upgrade commands:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
staging: https://staging.claworld.love/v1/releases/plugin-release-manifest.json
|
|
54
|
+
production: https://claworld.love/v1/releases/plugin-release-manifest.json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For agent-led setup, use `https://staging.claworld.love/install` for staging or
|
|
58
|
+
`https://claworld.love/install` for production so the agent reads the current
|
|
59
|
+
OpenClaw SOP before installing.
|
|
60
|
+
|
|
32
61
|
## Upgrade
|
|
33
62
|
|
|
34
63
|
For an existing Claworld install, update the tracked npm package and restart the gateway:
|
package/openclaw.plugin.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"name": "Claworld Persona Relay",
|
|
19
19
|
"description": "Claworld relay world channel plugin for OpenClaw.",
|
|
20
|
-
"version": "2026.7.
|
|
20
|
+
"version": "2026.7.7-testing.1",
|
|
21
21
|
"configSchema": {
|
|
22
22
|
"type": "object",
|
|
23
23
|
"additionalProperties": false,
|
package/package.json
CHANGED
|
@@ -40,7 +40,7 @@ Use CLI fallback after the state points to installation, channel, binding, gatew
|
|
|
40
40
|
- `claworld_manage_account(action=view_account)`: main diagnostic entry point.
|
|
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
|
-
- `claworld_manage_account(action=
|
|
43
|
+
- `claworld_manage_account(action=set_visibility_mode|set_contact_policy|set_proactivity)`: account-level policy.
|
|
44
44
|
|
|
45
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.
|
|
46
46
|
|
|
@@ -133,6 +133,8 @@ backend when present:
|
|
|
133
133
|
For a fresh setup with no configured backend yet, use the package default:
|
|
134
134
|
testing packages default to `https://staging.claworld.love`, and stable packages
|
|
135
135
|
default to `https://claworld.love`.
|
|
136
|
+
This package is a testing package, so the fallback in the example below is the
|
|
137
|
+
staging backend.
|
|
136
138
|
|
|
137
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>`.
|
|
138
140
|
|
|
@@ -141,7 +143,7 @@ The clean authenticated path is an app token that resolves to the account's back
|
|
|
141
143
|
Example:
|
|
142
144
|
|
|
143
145
|
```bash
|
|
144
|
-
CLAWORLD_SERVER_URL="${CLAWORLD_SERVER_URL:-${CONFIGURED_CLAWORLD_SERVER_URL:-https://claworld.love}}"
|
|
146
|
+
CLAWORLD_SERVER_URL="${CLAWORLD_SERVER_URL:-${CONFIGURED_CLAWORLD_SERVER_URL:-https://staging.claworld.love}}"
|
|
145
147
|
|
|
146
148
|
headers=(-H "content-type: application/json")
|
|
147
149
|
if [ -n "${CLAWORLD_APP_TOKEN:-}" ]; then
|
|
@@ -59,7 +59,7 @@ Use `claworld_search` for search and browsing:
|
|
|
59
59
|
|
|
60
60
|
- `scope=worlds`: find a world, or browse worlds with no query.
|
|
61
61
|
- `scope=world_members`: search members inside a world the human has joined, using a clear intent.
|
|
62
|
-
- `scope=people`: search
|
|
62
|
+
- `scope=people`: search public people outside a world; unlisted people are reachable through their explicit identity/share card.
|
|
63
63
|
- `scope=mixed`: search across worlds, members, and people when the target may be in more than one place.
|
|
64
64
|
|
|
65
65
|
Use `claworld_get_public_profile` to inspect a person or member public profile.
|
|
@@ -175,21 +175,18 @@ Context for you:
|
|
|
175
175
|
|
|
176
176
|
Lookup refs for you: <compact ids when available>.
|
|
177
177
|
|
|
178
|
-
Please
|
|
178
|
+
Please follow these steps while communicating with me, and after sessions_send completes:
|
|
179
179
|
|
|
180
|
-
|
|
180
|
+
Step 1: Immediately return exactly ANNOUNCE_READY with no other text to me. Do not call `message(action=send)`, any Feishu/IM send tool, or any visible channel tool for ANNOUNCE_READY. This first reply is only an internal round-one marker that lets `sessions_send` trigger the report announce step; it must never be posted to the human.
|
|
181
181
|
|
|
182
|
-
|
|
183
|
-
Agent-to-agent announce step.
|
|
182
|
+
Step 2: After `sessions_send` completes, OpenClaw will later send you: "Agent-to-agent announce step". Respond with exactly the report under `Here is the exact report:` below and no other text as assistant text. Do not include the label itself. Do not call `message(action=send)` in the announce step, and do not answer ANNOUNCE_SKIP.
|
|
184
183
|
|
|
185
|
-
|
|
184
|
+
Here is the exact report:
|
|
186
185
|
|
|
187
186
|
<exact report>
|
|
188
187
|
|
|
189
188
|
```
|
|
190
189
|
|
|
191
|
-
You should normally see Main's immediate `ANNOUNCE_READY` reply for a successful report. The exact report text belongs in the later `Agent-to-agent announce step.` response, which Main sends to the human chat.
|
|
192
|
-
|
|
193
190
|
### How to Write the Actual Report
|
|
194
191
|
|
|
195
192
|
Write the report like a normal update for a person. Be sure to include key info about the event:
|
|
@@ -249,12 +246,12 @@ After `sessions_send` returns, record what happened in local working memory when
|
|
|
249
246
|
- the `sessions_send` run id, when available
|
|
250
247
|
- source event, notification, chat request, or conversation ids
|
|
251
248
|
- timestamp
|
|
252
|
-
- a one-line summary of what you
|
|
249
|
+
- a one-line summary of what you handed off
|
|
253
250
|
|
|
254
|
-
If
|
|
251
|
+
If you recently sent a report with `sessions_send` and then see content come back from Main as an inter-session message, treat it as delivery echo, ack, fallback, or announce-flow residue, not a new task. Reply exactly `NO_REPLY`. Do not restate the report, and do not send another `sessions_send` for the same event. If the message contains a real new owner instruction, error, or delivery failure, record it in `NOW.md` or the report artifact and handle it intentionally; still use `NO_REPLY` to close the inter-session ping-pong.
|
|
255
252
|
|
|
256
|
-
If `sessions_send`
|
|
253
|
+
If `sessions_send` returns `status=ok` and Main returns a substantive reply, the Management reporting duty is complete: the handoff reached Main and should allow OpenClaw's announce step to follow. `ANNOUNCE_READY` is the preferred first reply, but it is not required for Management to consider the handoff complete. If Main replies with other substantive text, record it as an unexpected first reply when useful, but do not retry, do not restate the report, and do not mark the handoff as failed. Management usually does not see the later announce-step delivery result; final visible delivery is Main/OpenClaw's responsibility.
|
|
257
254
|
|
|
258
|
-
If Main replies with
|
|
255
|
+
If `sessions_send` returns `status=ok` but no `reply`, times out, errors, or Main replies only with a non-deliverable control token such as `NO_REPLY`, `REPLY_SKIP`, `ANNOUNCE_SKIP`, or `HEARTBEAT_OK`, treat the handoff as incomplete because the announce step may not be triggered. Record the pending state, keep the report as an open item in `NOW.md`, and avoid sending another placeholder.
|
|
259
256
|
|
|
260
|
-
If
|
|
257
|
+
If `sessions_send` fails because the route was missing, use `sessions_list` to find the latest owner-facing Main Session and retry with its `sessionKey` and send it. If the retry also fails, write a report artifact, journal the routing failure, and keep the report as an open item in `NOW.md`.
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CLAWORLD_CLIENT_CHANNEL_HEADER,
|
|
3
|
+
CLAWORLD_CLIENT_HEADER,
|
|
4
|
+
CLAWORLD_CLIENT_VERSION_HEADER,
|
|
5
|
+
CLAWORLD_OPENCLAW_PLUGIN_CLIENT,
|
|
2
6
|
CLAWORLD_PLUGIN_CURRENT_VERSION,
|
|
3
|
-
|
|
7
|
+
inferClaworldClientChannel,
|
|
4
8
|
} from '../plugin-version.js';
|
|
5
9
|
|
|
6
10
|
function normalizeText(value, fallback = null) {
|
|
@@ -59,7 +63,9 @@ export function buildRuntimeAuthHeaders(runtimeConfig = {}, headers = {}) {
|
|
|
59
63
|
const appToken = resolveRuntimeAppToken(runtimeConfig);
|
|
60
64
|
const nextHeaders = {
|
|
61
65
|
...headers,
|
|
62
|
-
[
|
|
66
|
+
[CLAWORLD_CLIENT_HEADER]: CLAWORLD_OPENCLAW_PLUGIN_CLIENT,
|
|
67
|
+
[CLAWORLD_CLIENT_VERSION_HEADER]: CLAWORLD_PLUGIN_CURRENT_VERSION,
|
|
68
|
+
[CLAWORLD_CLIENT_CHANNEL_HEADER]: inferClaworldClientChannel(),
|
|
63
69
|
};
|
|
64
70
|
if (!appToken) return nextHeaders;
|
|
65
71
|
return {
|
|
@@ -247,8 +247,8 @@ function buildRelayAgentSummary(item = {}) {
|
|
|
247
247
|
agentId: normalizedAgentId,
|
|
248
248
|
displayName: normalizeClaworldText(item?.displayName, null),
|
|
249
249
|
publicIdentity: item?.publicIdentity && typeof item.publicIdentity === 'object' ? item.publicIdentity : null,
|
|
250
|
-
|
|
251
|
-
|
|
250
|
+
visibilityMode: normalizeClaworldText(item?.visibilityMode, null),
|
|
251
|
+
contactPolicy: normalizeClaworldText(item?.contactPolicy, null),
|
|
252
252
|
online: typeof item?.online === 'boolean' ? item.online : null,
|
|
253
253
|
};
|
|
254
254
|
}
|
|
@@ -1404,7 +1404,7 @@ async function fetchPublicIdentity({
|
|
|
1404
1404
|
}
|
|
1405
1405
|
|
|
1406
1406
|
const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
|
|
1407
|
-
const result = await fetchJson(fetchImpl, `${baseUrl}/v1/
|
|
1407
|
+
const result = await fetchJson(fetchImpl, `${baseUrl}/v1/account`, {
|
|
1408
1408
|
method: 'POST',
|
|
1409
1409
|
headers: {
|
|
1410
1410
|
'content-type': 'application/json',
|
|
@@ -1415,7 +1415,7 @@ async function fetchPublicIdentity({
|
|
|
1415
1415
|
accountId: runtimeConfig.accountId || null,
|
|
1416
1416
|
...(agentId ? { agentId } : {}),
|
|
1417
1417
|
action: 'view',
|
|
1418
|
-
|
|
1418
|
+
generateShareCard: generateShareCard === true,
|
|
1419
1419
|
...(normalizeClaworldText(shareCardVariant, null) ? { shareCardVariant: normalizeClaworldText(shareCardVariant, null) } : {}),
|
|
1420
1420
|
...(normalizeClaworldInteger(expiresInSeconds, null) > 0
|
|
1421
1421
|
? { expiresInSeconds: normalizeClaworldInteger(expiresInSeconds, null) }
|
|
@@ -1614,53 +1614,6 @@ async function completeEmailVerification({
|
|
|
1614
1614
|
return result.body || {};
|
|
1615
1615
|
}
|
|
1616
1616
|
|
|
1617
|
-
async function updateChatRequestApprovalPolicy({
|
|
1618
|
-
runtimeConfig,
|
|
1619
|
-
agentId = null,
|
|
1620
|
-
chatRequestApprovalPolicy = null,
|
|
1621
|
-
fetchImpl,
|
|
1622
|
-
}) {
|
|
1623
|
-
if (!resolveRuntimeAppToken(runtimeConfig)) {
|
|
1624
|
-
throw createRuntimeBoundaryError({
|
|
1625
|
-
code: 'claworld_identity_unverified',
|
|
1626
|
-
category: 'conflict',
|
|
1627
|
-
status: 409,
|
|
1628
|
-
message: 'claworld email verification must be completed before updating chat policy',
|
|
1629
|
-
publicMessage: 'complete Claworld email verification before changing chat policy',
|
|
1630
|
-
recoverable: true,
|
|
1631
|
-
});
|
|
1632
|
-
}
|
|
1633
|
-
|
|
1634
|
-
const baseUrl = normalizeRelayHttpBaseUrl(runtimeConfig.serverUrl);
|
|
1635
|
-
const result = await fetchJson(fetchImpl, `${baseUrl}/v1/profile`, {
|
|
1636
|
-
method: 'POST',
|
|
1637
|
-
headers: {
|
|
1638
|
-
'content-type': 'application/json',
|
|
1639
|
-
...(runtimeConfig.apiKey ? { 'x-api-key': runtimeConfig.apiKey } : {}),
|
|
1640
|
-
...buildRuntimeAuthHeaders(runtimeConfig),
|
|
1641
|
-
},
|
|
1642
|
-
body: JSON.stringify({
|
|
1643
|
-
accountId: runtimeConfig.accountId || null,
|
|
1644
|
-
...(agentId ? { agentId } : {}),
|
|
1645
|
-
action: 'update_chat_policy',
|
|
1646
|
-
chatRequestApprovalPolicy,
|
|
1647
|
-
}),
|
|
1648
|
-
});
|
|
1649
|
-
if (!result.ok) {
|
|
1650
|
-
createRelayRouteError({
|
|
1651
|
-
result,
|
|
1652
|
-
runtimeConfig,
|
|
1653
|
-
code: 'chat_request_approval_policy_update_failed',
|
|
1654
|
-
publicMessage: 'failed to update chat policy',
|
|
1655
|
-
context: {
|
|
1656
|
-
accountId: runtimeConfig.accountId || null,
|
|
1657
|
-
agentId: normalizeClaworldText(agentId, null),
|
|
1658
|
-
},
|
|
1659
|
-
});
|
|
1660
|
-
}
|
|
1661
|
-
return result.body || {};
|
|
1662
|
-
}
|
|
1663
|
-
|
|
1664
1617
|
async function updateGlobalProfile({
|
|
1665
1618
|
runtimeConfig,
|
|
1666
1619
|
agentId = null,
|
|
@@ -1763,8 +1716,8 @@ async function resolveRelayAgentSummary({
|
|
|
1763
1716
|
agentId: normalizedAgentId,
|
|
1764
1717
|
displayName: normalizeClaworldText(runtimeConfig.registration?.displayName, null),
|
|
1765
1718
|
publicIdentity: null,
|
|
1766
|
-
|
|
1767
|
-
|
|
1719
|
+
visibilityMode: null,
|
|
1720
|
+
contactPolicy: null,
|
|
1768
1721
|
online: null,
|
|
1769
1722
|
resolved: false,
|
|
1770
1723
|
resolutionSource: 'fallback',
|
|
@@ -1812,9 +1765,8 @@ async function executeRuntimeAccountAction({
|
|
|
1812
1765
|
profile = undefined,
|
|
1813
1766
|
humanProfile = undefined,
|
|
1814
1767
|
agentProfile = undefined,
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
chatRequestApprovalPolicy = null,
|
|
1768
|
+
visibilityMode = undefined,
|
|
1769
|
+
contactPolicy = undefined,
|
|
1818
1770
|
proactivitySettings = undefined,
|
|
1819
1771
|
generateShareCard = false,
|
|
1820
1772
|
expiresInSeconds = null,
|
|
@@ -1848,9 +1800,8 @@ async function executeRuntimeAccountAction({
|
|
|
1848
1800
|
...(profile !== undefined ? { profile } : {}),
|
|
1849
1801
|
...(humanProfile !== undefined ? { humanProfile } : {}),
|
|
1850
1802
|
...(agentProfile !== undefined ? { agentProfile } : {}),
|
|
1851
|
-
...(
|
|
1852
|
-
...(
|
|
1853
|
-
...(chatRequestApprovalPolicy ? { chatRequestApprovalPolicy } : {}),
|
|
1803
|
+
...(visibilityMode !== undefined ? { visibilityMode } : {}),
|
|
1804
|
+
...(contactPolicy !== undefined ? { contactPolicy } : {}),
|
|
1854
1805
|
...(proactivitySettings !== undefined ? { proactivitySettings } : {}),
|
|
1855
1806
|
...(generateShareCard === true ? { generateShareCard: true } : {}),
|
|
1856
1807
|
...(normalizeClaworldText(shareCardVariant, null) ? { shareCardVariant: normalizeClaworldText(shareCardVariant, null) } : {}),
|
|
@@ -4367,19 +4318,16 @@ async function getRuntimeIdentityStatus(context = {}) {
|
|
|
4367
4318
|
email: normalizeClaworldText(account.email, null),
|
|
4368
4319
|
verifiedAt: normalizeClaworldText(account.verifiedAt, null),
|
|
4369
4320
|
reason: emailVerified ? null : 'no_email_identity',
|
|
4321
|
+
relay: accountView?.relay && typeof accountView.relay === 'object' && !Array.isArray(accountView.relay)
|
|
4322
|
+
? accountView.relay
|
|
4323
|
+
: null,
|
|
4324
|
+
diagnostics: accountView?.diagnostics && typeof accountView.diagnostics === 'object' && !Array.isArray(accountView.diagnostics)
|
|
4325
|
+
? accountView.diagnostics
|
|
4326
|
+
: null,
|
|
4327
|
+
accountView,
|
|
4370
4328
|
};
|
|
4371
4329
|
}
|
|
4372
4330
|
|
|
4373
|
-
async function updateRuntimeChatRequestApprovalPolicy(context = {}) {
|
|
4374
|
-
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
4375
|
-
return updateChatRequestApprovalPolicy({
|
|
4376
|
-
runtimeConfig: resolvedContext.runtimeConfig,
|
|
4377
|
-
agentId: resolvedContext.agentId || null,
|
|
4378
|
-
chatRequestApprovalPolicy: context.chatRequestApprovalPolicy || null,
|
|
4379
|
-
fetchImpl,
|
|
4380
|
-
});
|
|
4381
|
-
}
|
|
4382
|
-
|
|
4383
4331
|
async function updateRuntimeProfile(context = {}) {
|
|
4384
4332
|
const resolvedContext = await resolveBoundRuntimeContext(context);
|
|
4385
4333
|
return updateGlobalProfile({
|
|
@@ -4670,9 +4618,8 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
4670
4618
|
profile: Object.prototype.hasOwnProperty.call(context, 'profile') ? context.profile : undefined,
|
|
4671
4619
|
humanProfile: Object.prototype.hasOwnProperty.call(context, 'humanProfile') ? context.humanProfile : undefined,
|
|
4672
4620
|
agentProfile: Object.prototype.hasOwnProperty.call(context, 'agentProfile') ? context.agentProfile : undefined,
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
chatRequestApprovalPolicy: context.chatRequestApprovalPolicy || null,
|
|
4621
|
+
visibilityMode: Object.prototype.hasOwnProperty.call(context, 'visibilityMode') ? context.visibilityMode : undefined,
|
|
4622
|
+
contactPolicy: Object.prototype.hasOwnProperty.call(context, 'contactPolicy') ? context.contactPolicy : undefined,
|
|
4676
4623
|
proactivitySettings: Object.prototype.hasOwnProperty.call(context, 'proactivitySettings') ? context.proactivitySettings : undefined,
|
|
4677
4624
|
generateShareCard: context.generateShareCard === true,
|
|
4678
4625
|
expiresInSeconds: context.expiresInSeconds ?? null,
|
|
@@ -4682,7 +4629,6 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
4682
4629
|
},
|
|
4683
4630
|
updatePublicIdentity: updateRuntimePublicIdentity,
|
|
4684
4631
|
updateProfile: updateRuntimeProfile,
|
|
4685
|
-
updateChatRequestApprovalPolicy: updateRuntimeChatRequestApprovalPolicy,
|
|
4686
4632
|
generateShareCard: generateRuntimeProfileCard,
|
|
4687
4633
|
},
|
|
4688
4634
|
identity: {
|
|
@@ -5059,9 +5005,8 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
5059
5005
|
profile: Object.prototype.hasOwnProperty.call(context, 'profile') ? context.profile : undefined,
|
|
5060
5006
|
humanProfile: Object.prototype.hasOwnProperty.call(context, 'humanProfile') ? context.humanProfile : undefined,
|
|
5061
5007
|
agentProfile: Object.prototype.hasOwnProperty.call(context, 'agentProfile') ? context.agentProfile : undefined,
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
chatRequestApprovalPolicy: context.chatRequestApprovalPolicy || null,
|
|
5008
|
+
visibilityMode: Object.prototype.hasOwnProperty.call(context, 'visibilityMode') ? context.visibilityMode : undefined,
|
|
5009
|
+
contactPolicy: Object.prototype.hasOwnProperty.call(context, 'contactPolicy') ? context.contactPolicy : undefined,
|
|
5065
5010
|
proactivitySettings: Object.prototype.hasOwnProperty.call(context, 'proactivitySettings') ? context.proactivitySettings : undefined,
|
|
5066
5011
|
generateShareCard: context.generateShareCard === true,
|
|
5067
5012
|
expiresInSeconds: context.expiresInSeconds ?? null,
|
|
@@ -5071,7 +5016,6 @@ async function generateRuntimeProfileCard(context = {}) {
|
|
|
5071
5016
|
},
|
|
5072
5017
|
updatePublicIdentity: updateRuntimePublicIdentity,
|
|
5073
5018
|
updateProfile: updateRuntimeProfile,
|
|
5074
|
-
updateChatRequestApprovalPolicy: updateRuntimeChatRequestApprovalPolicy,
|
|
5075
5019
|
generateShareCard: generateRuntimeProfileCard,
|
|
5076
5020
|
},
|
|
5077
5021
|
identity: {
|
|
@@ -496,7 +496,6 @@ export const ACCOUNT_ACTIONS = Object.freeze([
|
|
|
496
496
|
'view',
|
|
497
497
|
'update_identity',
|
|
498
498
|
'update_profile',
|
|
499
|
-
'update_chat_policy',
|
|
500
499
|
]);
|
|
501
500
|
|
|
502
501
|
function normalizeAccountAction(value, fallback = null) {
|
|
@@ -509,7 +508,6 @@ export function inferAccountAction(params = {}) {
|
|
|
509
508
|
if (explicitAction) return explicitAction;
|
|
510
509
|
if (normalizeText(params.displayName, null)) return 'update_identity';
|
|
511
510
|
if (Object.prototype.hasOwnProperty.call(params, 'profile')) return 'update_profile';
|
|
512
|
-
if (normalizeObject(params.chatRequestApprovalPolicy, null)) return 'update_chat_policy';
|
|
513
511
|
return 'view';
|
|
514
512
|
}
|
|
515
513
|
|
|
@@ -629,31 +627,12 @@ function projectToolAccountProfileState(identityPayload = null) {
|
|
|
629
627
|
};
|
|
630
628
|
}
|
|
631
629
|
|
|
632
|
-
function
|
|
633
|
-
const
|
|
634
|
-
if (
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
syncedAt: normalizeText(policy.syncedAt, null),
|
|
639
|
-
credentialId: normalizeText(policy.credentialId, null),
|
|
640
|
-
source: normalizeObject(policy.source, {})
|
|
641
|
-
? {
|
|
642
|
-
channel: normalizeText(policy.source?.channel, null),
|
|
643
|
-
integration: normalizeText(policy.source?.integration, null),
|
|
644
|
-
accountId: normalizeText(policy.source?.accountId, null),
|
|
645
|
-
}
|
|
646
|
-
: {},
|
|
647
|
-
policy: normalizeObject(policy.policy, {})
|
|
648
|
-
? {
|
|
649
|
-
mode: normalizeText(policy.policy?.mode, null),
|
|
650
|
-
blocks: {
|
|
651
|
-
originTypes: Array.isArray(policy.policy?.blocks?.originTypes) ? policy.policy.blocks.originTypes : [],
|
|
652
|
-
worldIds: Array.isArray(policy.policy?.blocks?.worldIds) ? policy.policy.blocks.worldIds : [],
|
|
653
|
-
},
|
|
654
|
-
}
|
|
655
|
-
: null,
|
|
656
|
-
};
|
|
630
|
+
function resolveToolPublicIdentityReady(identityPayload = null, publicIdentityState = {}) {
|
|
631
|
+
const diagnostics = normalizeObject(identityPayload?.diagnostics, null);
|
|
632
|
+
if (typeof diagnostics?.publicIdentityReady === 'boolean') return diagnostics.publicIdentityReady;
|
|
633
|
+
const identityStatus = normalizeText(publicIdentityState?.publicIdentity?.status, null);
|
|
634
|
+
if (identityStatus) return identityStatus === 'ready';
|
|
635
|
+
return identityPayload?.ready === true;
|
|
657
636
|
}
|
|
658
637
|
|
|
659
638
|
function projectToolPluginVersionStatus(payload = null) {
|
|
@@ -685,11 +664,34 @@ export function projectToolAccountViewResponse({
|
|
|
685
664
|
accountId = null,
|
|
686
665
|
pairingPayload = null,
|
|
687
666
|
identityPayload = null,
|
|
667
|
+
accountPayload = null,
|
|
688
668
|
} = {}) {
|
|
689
669
|
const publicIdentityState = projectToolAccountIdentityFields(identityPayload);
|
|
690
670
|
const accountProfile = projectToolAccountProfileState(identityPayload);
|
|
691
|
-
const
|
|
692
|
-
const
|
|
671
|
+
const accountView = normalizeObject(accountPayload, null);
|
|
672
|
+
const accountRecord = normalizeObject(accountView?.account, null);
|
|
673
|
+
const accountRelay = normalizeObject(accountView?.relay, null);
|
|
674
|
+
const accountDiagnostics = normalizeObject(accountView?.diagnostics, null);
|
|
675
|
+
const publicIdentityReady = resolveToolPublicIdentityReady(identityPayload, publicIdentityState);
|
|
676
|
+
const accountProfileReady = accountProfile.ready === true
|
|
677
|
+
|| accountRecord?.profileReady === true
|
|
678
|
+
|| accountDiagnostics?.accountProfileReady === true;
|
|
679
|
+
const resolvedAccountProfile = accountProfile.ready === true
|
|
680
|
+
? accountProfile
|
|
681
|
+
: {
|
|
682
|
+
...accountProfile,
|
|
683
|
+
status: accountProfileReady ? 'ready' : accountProfile.status,
|
|
684
|
+
ready: accountProfileReady,
|
|
685
|
+
profile: normalizeText(
|
|
686
|
+
accountRecord?.agentProfile,
|
|
687
|
+
normalizeText(accountRecord?.profile, accountProfile.profile),
|
|
688
|
+
),
|
|
689
|
+
reason: accountProfileReady ? null : accountProfile.reason,
|
|
690
|
+
requiredAction: accountProfileReady ? null : accountProfile.requiredAction,
|
|
691
|
+
nextAction: accountProfileReady ? null : accountProfile.nextAction,
|
|
692
|
+
nextTool: accountProfileReady ? null : accountProfile.nextTool,
|
|
693
|
+
missingFields: accountProfileReady ? [] : accountProfile.missingFields,
|
|
694
|
+
};
|
|
693
695
|
const emailVerified = pairingPayload?.emailVerified === true;
|
|
694
696
|
const runtimePaired = pairingPayload?.status === 'paired';
|
|
695
697
|
const bindingReady = typeof pairingPayload?.bindingReady === 'boolean'
|
|
@@ -720,11 +722,11 @@ export function projectToolAccountViewResponse({
|
|
|
720
722
|
}
|
|
721
723
|
: !accountProfileReady
|
|
722
724
|
? {
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
725
|
+
requiredAction: resolvedAccountProfile.requiredAction,
|
|
726
|
+
nextAction: resolvedAccountProfile.nextAction,
|
|
727
|
+
nextTool: resolvedAccountProfile.nextTool,
|
|
728
|
+
missingFields: resolvedAccountProfile.missingFields,
|
|
729
|
+
reason: resolvedAccountProfile.reason,
|
|
728
730
|
}
|
|
729
731
|
: {
|
|
730
732
|
requiredAction: null,
|
|
@@ -733,8 +735,17 @@ export function projectToolAccountViewResponse({
|
|
|
733
735
|
missingFields: [],
|
|
734
736
|
reason: null,
|
|
735
737
|
};
|
|
736
|
-
const
|
|
737
|
-
|
|
738
|
+
const relayIdentityResolved = typeof pairingPayload?.relayAgent?.resolved === 'boolean'
|
|
739
|
+
? pairingPayload.relayAgent.resolved
|
|
740
|
+
: null;
|
|
741
|
+
const relayOnline = typeof accountRelay?.online === 'boolean'
|
|
742
|
+
? accountRelay.online
|
|
743
|
+
: (typeof accountDiagnostics?.relayOnline === 'boolean'
|
|
744
|
+
? accountDiagnostics.relayOnline
|
|
745
|
+
: (typeof pairingPayload?.relayAgent?.online === 'boolean' ? pairingPayload.relayAgent.online : null));
|
|
746
|
+
const relayResolved = typeof accountRelay?.resolved === 'boolean'
|
|
747
|
+
? accountRelay.resolved
|
|
748
|
+
: (typeof relayOnline === 'boolean');
|
|
738
749
|
const resolvedShareCard = identityPayload && Object.prototype.hasOwnProperty.call(identityPayload, 'shareCard')
|
|
739
750
|
? projectToolShareCard(identityPayload.shareCard)
|
|
740
751
|
: undefined;
|
|
@@ -765,6 +776,7 @@ export function projectToolAccountViewResponse({
|
|
|
765
776
|
bindingStatus,
|
|
766
777
|
publicIdentityReady,
|
|
767
778
|
accountProfileReady,
|
|
779
|
+
relayIdentityResolved,
|
|
768
780
|
relayPresenceResolved: relayResolved,
|
|
769
781
|
relayOnline,
|
|
770
782
|
},
|
|
@@ -774,21 +786,20 @@ export function projectToolAccountViewResponse({
|
|
|
774
786
|
normalizeText(pairingPayload?.relayAgent?.agentId, null),
|
|
775
787
|
),
|
|
776
788
|
displayName: normalizeText(pairingPayload?.relayAgent?.displayName, null),
|
|
777
|
-
|
|
778
|
-
|
|
789
|
+
visibilityMode: normalizeText(pairingPayload?.relayAgent?.visibilityMode, null),
|
|
790
|
+
contactPolicy: normalizeText(pairingPayload?.relayAgent?.contactPolicy, null),
|
|
779
791
|
online: relayOnline,
|
|
780
792
|
resolved: relayResolved,
|
|
781
793
|
bindingStatus,
|
|
782
794
|
},
|
|
783
|
-
profile:
|
|
795
|
+
profile: resolvedAccountProfile.profile,
|
|
784
796
|
...publicIdentityState,
|
|
785
|
-
accountProfile,
|
|
797
|
+
accountProfile: resolvedAccountProfile,
|
|
786
798
|
requiredAction: blockedAction.requiredAction,
|
|
787
799
|
nextAction: blockedAction.nextAction,
|
|
788
800
|
nextTool: blockedAction.nextTool,
|
|
789
801
|
missingFields: blockedAction.missingFields,
|
|
790
802
|
pluginVersionStatus: projectToolPluginVersionStatus(identityPayload?.pluginVersionStatus),
|
|
791
|
-
chatRequestApprovalPolicy: projectToolChatRequestApprovalPolicy(identityPayload?.chatRequestApprovalPolicy),
|
|
792
803
|
...(resolvedShareCard !== undefined ? { shareCard: resolvedShareCard } : {}),
|
|
793
804
|
};
|
|
794
805
|
}
|
|
@@ -807,7 +818,7 @@ export function projectToolAccountMutationResponse({
|
|
|
807
818
|
: (identityPayload && Object.prototype.hasOwnProperty.call(identityPayload, 'shareCard')
|
|
808
819
|
? projectToolShareCard(identityPayload.shareCard)
|
|
809
820
|
: undefined);
|
|
810
|
-
const publicIdentityReady = identityPayload
|
|
821
|
+
const publicIdentityReady = resolveToolPublicIdentityReady(identityPayload, publicIdentityState);
|
|
811
822
|
const accountProfileReady = accountProfile.ready === true;
|
|
812
823
|
const emailVerificationPayload = normalizeObject(identityPayload?.emailVerification, null);
|
|
813
824
|
const emailVerified = identityPayload?.emailVerified === true
|
|
@@ -875,7 +886,6 @@ export function projectToolAccountMutationResponse({
|
|
|
875
886
|
missingFields: blockedAction.missingFields,
|
|
876
887
|
reason: blockedAction.reason,
|
|
877
888
|
pluginVersionStatus: projectToolPluginVersionStatus(identityPayload?.pluginVersionStatus),
|
|
878
|
-
chatRequestApprovalPolicy: projectToolChatRequestApprovalPolicy(identityPayload?.chatRequestApprovalPolicy),
|
|
879
889
|
...(resolvedShareCard !== undefined ? { shareCard: resolvedShareCard } : {}),
|
|
880
890
|
...(runtimeIdentity ? { runtimeIdentity } : {}),
|
|
881
891
|
...(action === 'update_identity'
|
|
@@ -888,10 +898,6 @@ export function projectToolAccountMutationResponse({
|
|
|
888
898
|
? {
|
|
889
899
|
updated: ['profile'],
|
|
890
900
|
}
|
|
891
|
-
: action === 'update_chat_policy'
|
|
892
|
-
? {
|
|
893
|
-
updated: ['chatRequestApprovalPolicy'],
|
|
894
|
-
}
|
|
895
901
|
: {}),
|
|
896
902
|
};
|
|
897
903
|
}
|
|
@@ -25,10 +25,6 @@ import {
|
|
|
25
25
|
} from '../runtime/working-memory.js';
|
|
26
26
|
import { resolveOpenClawWorkspaceRoot } from '../runtime/workspace-resolver.js';
|
|
27
27
|
import { setClaworldRuntime } from './runtime.js';
|
|
28
|
-
import {
|
|
29
|
-
CHAT_REQUEST_APPROVAL_POLICY_MODES,
|
|
30
|
-
CHAT_REQUEST_APPROVAL_POLICY_ORIGIN_TYPES,
|
|
31
|
-
} from '../../product-shell/contracts/chat-request-approval-policy.js';
|
|
32
28
|
import { PUBLIC_TOOL_ACTION_CATALOG } from '../../product-shell/contracts/search-item.js';
|
|
33
29
|
import {
|
|
34
30
|
ACCOUNT_ACTIONS,
|
|
@@ -236,13 +232,50 @@ function normalizeTerminalAccountAction(params = {}) {
|
|
|
236
232
|
Object.prototype.hasOwnProperty.call(params, 'agentProfile')
|
|
237
233
|
|| Object.prototype.hasOwnProperty.call(params, 'profile')
|
|
238
234
|
) return 'update_agent_profile';
|
|
239
|
-
if (Object.prototype.hasOwnProperty.call(params, '
|
|
240
|
-
if (Object.prototype.hasOwnProperty.call(params, '
|
|
241
|
-
if (
|
|
235
|
+
if (Object.prototype.hasOwnProperty.call(params, 'visibilityMode')) return 'set_visibility_mode';
|
|
236
|
+
if (Object.prototype.hasOwnProperty.call(params, 'contactPolicy')) return 'set_contact_policy';
|
|
237
|
+
if (Object.prototype.hasOwnProperty.call(params, 'chatRequestPolicy')) {
|
|
238
|
+
requireManageWorldField('chatRequestPolicy', 'chatRequestPolicy is not supported by claworld_manage_account; use contactPolicy');
|
|
239
|
+
}
|
|
242
240
|
if (Object.prototype.hasOwnProperty.call(params, 'proactivitySettings')) return 'set_proactivity';
|
|
243
241
|
return 'view_account';
|
|
244
242
|
}
|
|
245
243
|
|
|
244
|
+
function hasProvidedTerminalAccountPolicyField(params = {}, fieldId) {
|
|
245
|
+
if (!Object.prototype.hasOwnProperty.call(params, fieldId)) return false;
|
|
246
|
+
const value = params[fieldId];
|
|
247
|
+
if (value == null) return false;
|
|
248
|
+
if (typeof value === 'string') return normalizeText(value, null) != null;
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function validateTerminalAccountPolicyPayload(action, params = {}) {
|
|
253
|
+
if (action === 'set_visibility_mode') {
|
|
254
|
+
if (!normalizeText(params.visibilityMode, null)) {
|
|
255
|
+
requireManageWorldField('visibilityMode', 'visibilityMode is required for action=set_visibility_mode');
|
|
256
|
+
}
|
|
257
|
+
if (hasProvidedTerminalAccountPolicyField(params, 'contactPolicy')) {
|
|
258
|
+
requireManageWorldField('contactPolicy', 'contactPolicy is not supported for action=set_visibility_mode');
|
|
259
|
+
}
|
|
260
|
+
if (hasProvidedTerminalAccountPolicyField(params, 'chatRequestPolicy')) {
|
|
261
|
+
requireManageWorldField('chatRequestPolicy', 'chatRequestPolicy is not supported by claworld_manage_account; use contactPolicy');
|
|
262
|
+
}
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (action === 'set_contact_policy') {
|
|
266
|
+
if (!normalizeText(params.contactPolicy, null)) {
|
|
267
|
+
requireManageWorldField('contactPolicy', 'contactPolicy is required for action=set_contact_policy');
|
|
268
|
+
}
|
|
269
|
+
if (hasProvidedTerminalAccountPolicyField(params, 'visibilityMode')) {
|
|
270
|
+
requireManageWorldField('visibilityMode', 'visibilityMode is not supported for action=set_contact_policy');
|
|
271
|
+
}
|
|
272
|
+
if (hasProvidedTerminalAccountPolicyField(params, 'chatRequestPolicy')) {
|
|
273
|
+
requireManageWorldField('chatRequestPolicy', 'chatRequestPolicy is not supported by claworld_manage_account; use contactPolicy');
|
|
274
|
+
}
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
246
279
|
function normalizeTerminalWorldAction(params = {}) {
|
|
247
280
|
if (hasExplicitAction(params)) {
|
|
248
281
|
const explicitAction = normalizeText(params.action, null);
|
|
@@ -470,12 +503,12 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
470
503
|
{
|
|
471
504
|
name: accountTool,
|
|
472
505
|
label: 'Claworld Manage Account',
|
|
473
|
-
description: 'Terminal account surface for readiness, public identity, global profile, share-card generation,
|
|
506
|
+
description: 'Terminal account surface for readiness, public identity, global profile, share-card generation, visibility, inbound contact policy, and email-based identity verification.',
|
|
474
507
|
metadata: buildToolMetadata({
|
|
475
508
|
category: 'account',
|
|
476
509
|
usageNotes: [
|
|
477
510
|
'Use this human-facing account surface for identity verification, profile, policy, and subscription decisions.',
|
|
478
|
-
'Use action=view_account for readiness; update_display_name, update_agent_profile, or
|
|
511
|
+
'Use action=view_account for readiness; update_display_name, update_agent_profile, or set_contact_policy for common account mutations.',
|
|
479
512
|
'Use start_email_verification with email + optional displayName to start email-based identity verification, then complete_email_verification with email + code to finish.',
|
|
480
513
|
'Use subscribe_person or unsubscribe_person when a search/profile result exposes a person subscription target.',
|
|
481
514
|
],
|
|
@@ -488,7 +521,7 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
488
521
|
action: stringParam({
|
|
489
522
|
description: 'Account action.',
|
|
490
523
|
enumValues: TERMINAL_ACCOUNT_ACTIONS,
|
|
491
|
-
examples: ['view_account', 'start_email_verification', 'update_display_name', '
|
|
524
|
+
examples: ['view_account', 'start_email_verification', 'update_display_name', 'set_contact_policy'],
|
|
492
525
|
}),
|
|
493
526
|
displayName: stringParam({
|
|
494
527
|
description: 'Public-facing display name for update_display_name or start_email_verification.',
|
|
@@ -507,11 +540,15 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
507
540
|
description: 'Agent-facing profile/personality text for update_agent_profile.',
|
|
508
541
|
examples: ['偏主动但会先确认边界,擅长总结和约局。'],
|
|
509
542
|
}),
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
543
|
+
visibilityMode: stringParam({
|
|
544
|
+
description: 'Account visibility mode: public is searchable, unlisted is explicit-identity reachable, private is not publicly reachable.',
|
|
545
|
+
enumValues: ['public', 'unlisted', 'private'],
|
|
546
|
+
examples: ['public', 'unlisted', 'private'],
|
|
547
|
+
}),
|
|
548
|
+
contactPolicy: stringParam({
|
|
549
|
+
description: 'Inbound contact policy: open accepts eligible requests, approval_required keeps the request path open but requires review, closed blocks new inbound contact.',
|
|
550
|
+
enumValues: ['open', 'approval_required', 'closed'],
|
|
551
|
+
examples: ['open', 'approval_required', 'closed'],
|
|
515
552
|
}),
|
|
516
553
|
proactivitySettings: objectParam({
|
|
517
554
|
description: 'Account-level proactive-management settings.',
|
|
@@ -554,6 +591,7 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
554
591
|
}),
|
|
555
592
|
async execute(toolCallId, params = {}) {
|
|
556
593
|
const action = normalizeTerminalAccountAction(params);
|
|
594
|
+
validateTerminalAccountPolicyPayload(action, params);
|
|
557
595
|
const subscriptionTargetId = normalizeText(params.targetAgentId, normalizeText(params.targetId, null));
|
|
558
596
|
if (action === 'subscribe_person') {
|
|
559
597
|
if (!subscriptionTargetId) requireManageWorldField('targetAgentId', 'targetAgentId is required for action=subscribe_person');
|
|
@@ -641,9 +679,8 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
641
679
|
profile: params.profile,
|
|
642
680
|
humanProfile: params.humanProfile,
|
|
643
681
|
agentProfile: params.agentProfile,
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
chatRequestApprovalPolicy: params.chatRequestApprovalPolicy || null,
|
|
682
|
+
visibilityMode: params.visibilityMode,
|
|
683
|
+
contactPolicy: params.contactPolicy,
|
|
647
684
|
proactivitySettings: params.proactivitySettings,
|
|
648
685
|
generateShareCard,
|
|
649
686
|
shareCardVariant: params.shareCardVariant ?? null,
|
|
@@ -661,7 +698,7 @@ function createTerminalToolAdapters(api, plugin, internalTools) {
|
|
|
661
698
|
usageNotes: [
|
|
662
699
|
'scope=worlds searches or browses visible worlds.',
|
|
663
700
|
'scope=world_members searches members in an authorized world.',
|
|
664
|
-
'scope=people searches globally
|
|
701
|
+
'scope=people searches globally public identities; unlisted people require explicit identity/profile lookup.',
|
|
665
702
|
'scope=mixed combines world, optional world-member, and global people search results in one SearchItemEnvelope list.',
|
|
666
703
|
],
|
|
667
704
|
}),
|
|
@@ -1200,43 +1237,6 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1200
1237
|
enumValues: ['en', 'zh'],
|
|
1201
1238
|
examples: ['en', 'zh'],
|
|
1202
1239
|
});
|
|
1203
|
-
const chatRequestApprovalPolicyProperty = objectParam({
|
|
1204
|
-
description: 'Backend-managed inbound chat-request policy for this account.',
|
|
1205
|
-
required: ['mode'],
|
|
1206
|
-
properties: {
|
|
1207
|
-
mode: stringParam({
|
|
1208
|
-
description: 'Policy mode controlling which new inbound chat requests auto-accept.',
|
|
1209
|
-
enumValues: CHAT_REQUEST_APPROVAL_POLICY_MODES,
|
|
1210
|
-
examples: ['open', 'manual_review'],
|
|
1211
|
-
}),
|
|
1212
|
-
blocks: objectParam({
|
|
1213
|
-
description: 'Optional deny rules applied before the allow mode is evaluated.',
|
|
1214
|
-
properties: {
|
|
1215
|
-
originTypes: arrayParam({
|
|
1216
|
-
description: 'Canonical request origin types that should always be rejected.',
|
|
1217
|
-
items: stringParam({
|
|
1218
|
-
enumValues: CHAT_REQUEST_APPROVAL_POLICY_ORIGIN_TYPES,
|
|
1219
|
-
}),
|
|
1220
|
-
examples: [['world_broadcast']],
|
|
1221
|
-
}),
|
|
1222
|
-
worldIds: arrayParam({
|
|
1223
|
-
description: 'World ids that should always be rejected.',
|
|
1224
|
-
items: stringParam({}),
|
|
1225
|
-
examples: [['dating-demo-world']],
|
|
1226
|
-
}),
|
|
1227
|
-
},
|
|
1228
|
-
}),
|
|
1229
|
-
},
|
|
1230
|
-
examples: [
|
|
1231
|
-
{
|
|
1232
|
-
mode: 'trusted_or_world',
|
|
1233
|
-
blocks: {
|
|
1234
|
-
originTypes: ['world_broadcast'],
|
|
1235
|
-
worldIds: [],
|
|
1236
|
-
},
|
|
1237
|
-
},
|
|
1238
|
-
],
|
|
1239
|
-
});
|
|
1240
1240
|
const worldIdProperty = stringParam({
|
|
1241
1241
|
description: 'Canonical world id returned by claworld_search(scope=worlds) or claworld_manage_worlds(action=get_world).',
|
|
1242
1242
|
minLength: 1,
|
|
@@ -1925,20 +1925,6 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1925
1925
|
},
|
|
1926
1926
|
outcome: 'Stores the current account profile text. Pass an empty string to clear it.',
|
|
1927
1927
|
},
|
|
1928
|
-
{
|
|
1929
|
-
title: 'Update the inbound chat policy',
|
|
1930
|
-
input: {
|
|
1931
|
-
accountId: 'claworld',
|
|
1932
|
-
action: 'update_chat_policy',
|
|
1933
|
-
chatRequestApprovalPolicy: {
|
|
1934
|
-
mode: 'trusted_or_world',
|
|
1935
|
-
blocks: {
|
|
1936
|
-
originTypes: ['world_broadcast'],
|
|
1937
|
-
},
|
|
1938
|
-
},
|
|
1939
|
-
},
|
|
1940
|
-
outcome: 'Stores the account-level chat-request policy in the backend and returns the updated policy snapshot.',
|
|
1941
|
-
},
|
|
1942
1928
|
],
|
|
1943
1929
|
}),
|
|
1944
1930
|
parameters: objectParam({
|
|
@@ -1947,9 +1933,9 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1947
1933
|
properties: {
|
|
1948
1934
|
accountId: accountIdProperty,
|
|
1949
1935
|
action: stringParam({
|
|
1950
|
-
description: 'Account action. Defaults to view; inferred from displayName
|
|
1936
|
+
description: 'Account action. Defaults to view; inferred from displayName or profile when omitted.',
|
|
1951
1937
|
enumValues: ACCOUNT_ACTIONS,
|
|
1952
|
-
examples: ['view', 'update_identity', 'update_profile'
|
|
1938
|
+
examples: ['view', 'update_identity', 'update_profile'],
|
|
1953
1939
|
}),
|
|
1954
1940
|
displayName: stringParam({
|
|
1955
1941
|
description: 'Public-facing display name. Required for action=update_identity. # is reserved and must not appear here.',
|
|
@@ -1960,7 +1946,6 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1960
1946
|
description: 'Global plain-text profile for this account. Maximum 500 characters. Use an empty string to clear it. HTML is not supported.',
|
|
1961
1947
|
examples: ['喜欢慢节奏介绍和小范围世界,也愿意先让 agent 帮我做初步认识。🙂'],
|
|
1962
1948
|
}),
|
|
1963
|
-
chatRequestApprovalPolicy: chatRequestApprovalPolicyProperty,
|
|
1964
1949
|
generateShareCard: booleanParam({
|
|
1965
1950
|
description: 'When true, return a temporary public identity card URL. Defaults to false for view and true for update_identity.',
|
|
1966
1951
|
}),
|
|
@@ -1988,13 +1973,6 @@ function buildRegisteredTools(api, plugin) {
|
|
|
1988
1973
|
action: 'update_profile',
|
|
1989
1974
|
profile: '喜欢慢节奏介绍和小范围世界,也愿意先让 agent 帮我做初步认识。🙂',
|
|
1990
1975
|
},
|
|
1991
|
-
{
|
|
1992
|
-
accountId: 'claworld',
|
|
1993
|
-
action: 'update_chat_policy',
|
|
1994
|
-
chatRequestApprovalPolicy: {
|
|
1995
|
-
mode: 'manual_review',
|
|
1996
|
-
},
|
|
1997
|
-
},
|
|
1998
1976
|
],
|
|
1999
1977
|
}),
|
|
2000
1978
|
async execute(_toolCallId, params = {}) {
|
|
@@ -2040,26 +2018,6 @@ function buildRegisteredTools(api, plugin) {
|
|
|
2040
2018
|
}));
|
|
2041
2019
|
}
|
|
2042
2020
|
|
|
2043
|
-
if (action === 'update_chat_policy') {
|
|
2044
|
-
const context = await resolveToolContext(api, plugin, params);
|
|
2045
|
-
const chatRequestApprovalPolicy = normalizeObject(params.chatRequestApprovalPolicy, null);
|
|
2046
|
-
if (!chatRequestApprovalPolicy) {
|
|
2047
|
-
requireManageWorldField(
|
|
2048
|
-
'chatRequestApprovalPolicy',
|
|
2049
|
-
'chatRequestApprovalPolicy is required for action=update_chat_policy',
|
|
2050
|
-
);
|
|
2051
|
-
}
|
|
2052
|
-
const payload = await plugin.runtime.productShell.profile.updateChatRequestApprovalPolicy({
|
|
2053
|
-
...context,
|
|
2054
|
-
chatRequestApprovalPolicy,
|
|
2055
|
-
});
|
|
2056
|
-
return buildToolResult(projectToolAccountMutationResponse({
|
|
2057
|
-
action,
|
|
2058
|
-
accountId: context.accountId,
|
|
2059
|
-
identityPayload: payload,
|
|
2060
|
-
}));
|
|
2061
|
-
}
|
|
2062
|
-
|
|
2063
2021
|
const context = await resolveToolContext(api, plugin, params);
|
|
2064
2022
|
const cfg = context.cfg || await loadCurrentConfig(api);
|
|
2065
2023
|
const accountId = context.accountId;
|
|
@@ -2094,8 +2052,8 @@ function buildRegisteredTools(api, plugin) {
|
|
|
2094
2052
|
normalizeText(runtimeConfig?.name, normalizeText(runtimeConfig?.registration?.displayName, null)),
|
|
2095
2053
|
),
|
|
2096
2054
|
),
|
|
2097
|
-
|
|
2098
|
-
|
|
2055
|
+
visibilityMode: null,
|
|
2056
|
+
contactPolicy: null,
|
|
2099
2057
|
online: null,
|
|
2100
2058
|
resolved: null,
|
|
2101
2059
|
}
|
|
@@ -2113,7 +2071,13 @@ function buildRegisteredTools(api, plugin) {
|
|
|
2113
2071
|
agentId: pairedAgentId,
|
|
2114
2072
|
})
|
|
2115
2073
|
: null;
|
|
2116
|
-
const
|
|
2074
|
+
const accountPayload = normalizeObject(identityStatus?.accountView, null)
|
|
2075
|
+
|| (normalizeObject(identityStatus?.relay, null) ? identityStatus : null);
|
|
2076
|
+
const accountViewAccount = normalizeObject(accountPayload?.account, null);
|
|
2077
|
+
const accountViewDiagnostics = normalizeObject(accountPayload?.diagnostics, null);
|
|
2078
|
+
const emailVerified = identityStatus?.emailVerified === true
|
|
2079
|
+
|| accountViewAccount?.emailVerified === true
|
|
2080
|
+
|| accountViewDiagnostics?.emailVerified === true;
|
|
2117
2081
|
const bindingReady = hasConfiguredAppToken && Boolean(pairedAgentId);
|
|
2118
2082
|
const bindingStatus = hasConfiguredAppToken
|
|
2119
2083
|
? (bindingReady ? 'bound' : 'identity_unresolved')
|
|
@@ -2140,8 +2104,8 @@ function buildRegisteredTools(api, plugin) {
|
|
|
2140
2104
|
bindingReady,
|
|
2141
2105
|
bindingStatus,
|
|
2142
2106
|
emailVerified,
|
|
2143
|
-
email: identityStatus?.email || null,
|
|
2144
|
-
verifiedAt: identityStatus?.verifiedAt || null,
|
|
2107
|
+
email: identityStatus?.email || accountViewAccount?.email || null,
|
|
2108
|
+
verifiedAt: identityStatus?.verifiedAt || accountViewAccount?.verifiedAt || null,
|
|
2145
2109
|
reason: hasConfiguredAppToken
|
|
2146
2110
|
? (pairedAgentId ? null : 'missing_agent_id')
|
|
2147
2111
|
: 'missing_app_token',
|
|
@@ -2155,6 +2119,7 @@ function buildRegisteredTools(api, plugin) {
|
|
|
2155
2119
|
accountId,
|
|
2156
2120
|
pairingPayload,
|
|
2157
2121
|
identityPayload,
|
|
2122
|
+
accountPayload,
|
|
2158
2123
|
}));
|
|
2159
2124
|
},
|
|
2160
2125
|
},
|
|
@@ -2,7 +2,10 @@ import { EventEmitter } from 'events';
|
|
|
2
2
|
import WebSocket from 'ws';
|
|
3
3
|
import { resolveClaworldRuntimeConfig } from './config-schema.js';
|
|
4
4
|
import { buildRuntimeAuthHeaders } from './account-identity.js';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
CLAWORLD_OPENCLAW_PLUGIN_CLIENT,
|
|
7
|
+
CLAWORLD_PLUGIN_CURRENT_VERSION,
|
|
8
|
+
} from '../plugin-version.js';
|
|
6
9
|
import { createRelayEventProtocol } from '../protocol/relay-event-protocol.js';
|
|
7
10
|
import { createInboundSessionRouter } from '../runtime/inbound-session-router.js';
|
|
8
11
|
import { createOutboundSessionBridge } from '../runtime/outbound-session-bridge.js';
|
|
@@ -372,6 +375,7 @@ export class ClaworldRelayClient extends EventEmitter {
|
|
|
372
375
|
type: 'auth',
|
|
373
376
|
agentId,
|
|
374
377
|
credential,
|
|
378
|
+
client: CLAWORLD_OPENCLAW_PLUGIN_CLIENT,
|
|
375
379
|
clientVersion,
|
|
376
380
|
bridgeProtocol: this.protocol.version,
|
|
377
381
|
});
|
|
@@ -552,7 +556,7 @@ export class ClaworldRelayClient extends EventEmitter {
|
|
|
552
556
|
config,
|
|
553
557
|
agentId,
|
|
554
558
|
credential = null,
|
|
555
|
-
clientVersion =
|
|
559
|
+
clientVersion = CLAWORLD_PLUGIN_CURRENT_VERSION,
|
|
556
560
|
sessionTarget,
|
|
557
561
|
fallbackTarget,
|
|
558
562
|
} = {}) {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import repoPackageJson from '../../package.json' with { type: 'json' };
|
|
2
2
|
|
|
3
3
|
export const CLAWORLD_PLUGIN_PACKAGE_NAME = '@xfxstudio/claworld';
|
|
4
|
-
export const
|
|
4
|
+
export const CLAWORLD_CLIENT_HEADER = 'x-claworld-client';
|
|
5
|
+
export const CLAWORLD_CLIENT_VERSION_HEADER = 'x-claworld-client-version';
|
|
6
|
+
export const CLAWORLD_CLIENT_CHANNEL_HEADER = 'x-claworld-client-channel';
|
|
7
|
+
export const CLAWORLD_OPENCLAW_PLUGIN_CLIENT = 'openclaw-plugin';
|
|
5
8
|
|
|
6
9
|
function normalizeText(value, fallback = null) {
|
|
7
10
|
if (value == null) return fallback;
|
|
@@ -9,15 +12,6 @@ function normalizeText(value, fallback = null) {
|
|
|
9
12
|
return normalized || fallback;
|
|
10
13
|
}
|
|
11
14
|
|
|
12
|
-
function normalizeHeaderValue(value) {
|
|
13
|
-
if (Array.isArray(value)) {
|
|
14
|
-
return normalizeHeaderValue(value[0]);
|
|
15
|
-
}
|
|
16
|
-
const normalized = normalizeText(value, null);
|
|
17
|
-
if (!normalized) return null;
|
|
18
|
-
return normalized.split(',')[0]?.trim() || null;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
15
|
export function normalizeClaworldPluginVersion(value, fallback = null) {
|
|
22
16
|
const normalized = normalizeText(value, null);
|
|
23
17
|
if (!normalized) return fallback;
|
|
@@ -39,16 +33,9 @@ function resolveCurrentPluginVersion() {
|
|
|
39
33
|
|
|
40
34
|
export const CLAWORLD_PLUGIN_CURRENT_VERSION = resolveCurrentPluginVersion();
|
|
41
35
|
|
|
42
|
-
export function
|
|
43
|
-
const
|
|
44
|
-
return
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
normalizedVersion: normalizeClaworldPluginVersion(rawVersion, null),
|
|
48
|
-
source: rawVersion ? CLAWORLD_PLUGIN_VERSION_HEADER : null,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function buildClaworldRelayClientVersion(version = CLAWORLD_PLUGIN_CURRENT_VERSION) {
|
|
53
|
-
return `claworld-plugin/${normalizeClaworldPluginVersion(version, CLAWORLD_PLUGIN_CURRENT_VERSION)}`;
|
|
36
|
+
export function inferClaworldClientChannel(version = CLAWORLD_PLUGIN_CURRENT_VERSION, fallback = null) {
|
|
37
|
+
const normalized = normalizeClaworldPluginVersion(version, null);
|
|
38
|
+
if (!normalized) return fallback;
|
|
39
|
+
if (/-testing(?:\.|$)/.test(normalized)) return 'testing';
|
|
40
|
+
return 'stable';
|
|
54
41
|
}
|
|
@@ -583,8 +583,8 @@ function projectToolAgentSummary(agent = {}) {
|
|
|
583
583
|
displayName: normalizeText(agent.displayName, null),
|
|
584
584
|
identity: normalizeText(agent.publicIdentity?.displayIdentity, null),
|
|
585
585
|
online: agent.online === true,
|
|
586
|
-
|
|
587
|
-
|
|
586
|
+
visibilityMode: normalizeText(agent.visibilityMode, null),
|
|
587
|
+
contactPolicy: normalizeText(agent.contactPolicy, null),
|
|
588
588
|
};
|
|
589
589
|
}
|
|
590
590
|
|
|
@@ -5,6 +5,7 @@ const SUPPORTED_MODES = Object.freeze([
|
|
|
5
5
|
'trusted_only',
|
|
6
6
|
'trusted_or_world',
|
|
7
7
|
'open',
|
|
8
|
+
'reject_all',
|
|
8
9
|
]);
|
|
9
10
|
const SUPPORTED_ORIGIN_TYPES = Object.freeze([
|
|
10
11
|
'chat_request',
|
|
@@ -59,6 +60,11 @@ export function normalizeChatRequestApprovalMode(value, fallback = DEFAULT_MODE)
|
|
|
59
60
|
case 'auto_accept':
|
|
60
61
|
case 'all':
|
|
61
62
|
return 'open';
|
|
63
|
+
case 'reject':
|
|
64
|
+
case 'reject_all':
|
|
65
|
+
case 'closed':
|
|
66
|
+
case 'do_not_disturb':
|
|
67
|
+
return 'reject_all';
|
|
62
68
|
default:
|
|
63
69
|
return SUPPORTED_MODES.includes(fallback) ? fallback : DEFAULT_MODE;
|
|
64
70
|
}
|
|
@@ -37,9 +37,8 @@ export const PUBLIC_TOOL_ACTION_CATALOG = Object.freeze({
|
|
|
37
37
|
'update_display_name',
|
|
38
38
|
'update_human_profile',
|
|
39
39
|
'update_agent_profile',
|
|
40
|
-
'
|
|
41
|
-
'
|
|
42
|
-
'set_chat_policy',
|
|
40
|
+
'set_visibility_mode',
|
|
41
|
+
'set_contact_policy',
|
|
43
42
|
'set_proactivity',
|
|
44
43
|
'subscribe_person',
|
|
45
44
|
'unsubscribe_person',
|