@xfxstudio/claworld 2026.4.14-testing.1 → 2026.4.16-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/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/index.js +0 -50
- package/setup-entry.js +0 -6
- package/skills/claworld-a2a-channel-agent/SKILL.md +0 -218
- package/skills/claworld-help/SKILL.md +0 -304
- package/skills/claworld-join-and-chat/SKILL.md +0 -515
- package/skills/claworld-manage-worlds/SKILL.md +0 -283
- package/skills/claworld-manage-worlds/references/world-context-templates.md +0 -145
- package/src/lib/chat-request.js +0 -366
- package/src/lib/public-identity.js +0 -175
- package/src/lib/relay/agent-readable-markdown.js +0 -385
- package/src/lib/relay/kickoff-progress.js +0 -162
- package/src/lib/relay/kickoff-text.js +0 -191
- package/src/lib/relay/shared.js +0 -30
- package/src/lib/runtime-errors.js +0 -149
- package/src/openclaw/index.js +0 -51
- package/src/openclaw/plugin/account-identity.js +0 -73
- package/src/openclaw/plugin/claworld-channel-plugin.js +0 -3483
- package/src/openclaw/plugin/config-schema.js +0 -392
- package/src/openclaw/plugin/lifecycle.js +0 -114
- package/src/openclaw/plugin/managed-config.js +0 -1054
- package/src/openclaw/plugin/onboarding.js +0 -312
- package/src/openclaw/plugin/register-tooling.js +0 -728
- package/src/openclaw/plugin/register.js +0 -1609
- package/src/openclaw/plugin/relay-client-shared.js +0 -146
- package/src/openclaw/plugin/relay-client.js +0 -1469
- package/src/openclaw/plugin/runtime-backup.js +0 -105
- package/src/openclaw/plugin/runtime.js +0 -12
- package/src/openclaw/plugin-version.js +0 -67
- package/src/openclaw/protocol/relay-event-protocol.js +0 -43
- package/src/openclaw/runtime/backend-error-context.js +0 -91
- package/src/openclaw/runtime/canonical-result-builder.js +0 -126
- package/src/openclaw/runtime/demo-session-bootstrap.js +0 -32
- package/src/openclaw/runtime/feedback-helper.js +0 -145
- package/src/openclaw/runtime/inbound-session-router.js +0 -44
- package/src/openclaw/runtime/outbound-session-bridge.js +0 -29
- package/src/openclaw/runtime/product-shell-helper.js +0 -931
- package/src/openclaw/runtime/runtime-path.js +0 -19
- package/src/openclaw/runtime/system-message-orchestrator.js +0 -1
- package/src/openclaw/runtime/tool-contracts.js +0 -939
- package/src/openclaw/runtime/tool-inventory.js +0 -83
- package/src/openclaw/runtime/world-membership-helper.js +0 -320
- package/src/openclaw/runtime/world-moderation-helper.js +0 -508
- package/src/product-shell/contracts/chat-request-approval-policy.js +0 -93
- package/src/product-shell/contracts/world-orchestration.js +0 -734
- package/src/product-shell/orchestration/world-conversation-text.js +0 -229
|
@@ -1,508 +0,0 @@
|
|
|
1
|
-
import { resolveClaworldRuntimeConfig } from '../plugin/config-schema.js';
|
|
2
|
-
import { buildRuntimeAuthHeaders } from '../plugin/account-identity.js';
|
|
3
|
-
import { createRuntimeBoundaryError } from '../../lib/runtime-errors.js';
|
|
4
|
-
import { extractBackendErrorContext } from './backend-error-context.js';
|
|
5
|
-
import { normalizeWorldJoinResponse } from './product-shell-helper.js';
|
|
6
|
-
|
|
7
|
-
function normalizeText(value, fallback = null) {
|
|
8
|
-
if (value == null) return fallback;
|
|
9
|
-
const normalized = String(value).trim();
|
|
10
|
-
return normalized || fallback;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function normalizeInteger(value, fallback = 0) {
|
|
14
|
-
const parsed = Number(value);
|
|
15
|
-
if (!Number.isFinite(parsed)) return fallback;
|
|
16
|
-
return Math.max(0, Math.trunc(parsed));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function normalizeOptionalBoolean(value, fallback = null) {
|
|
20
|
-
if (typeof value === 'boolean') return value;
|
|
21
|
-
return fallback;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function normalizeOptionalInteger(value, fallback = null) {
|
|
25
|
-
const parsed = Number(value);
|
|
26
|
-
if (!Number.isFinite(parsed)) return fallback;
|
|
27
|
-
return Math.trunc(parsed);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function normalizePositiveInteger(value, fallback = null) {
|
|
31
|
-
const parsed = Number(value);
|
|
32
|
-
if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
|
|
33
|
-
return Math.max(1, Math.trunc(parsed));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function normalizeStringList(values = []) {
|
|
37
|
-
if (!Array.isArray(values)) return [];
|
|
38
|
-
return [...new Set(values.map((value) => normalizeText(value, null)).filter(Boolean))];
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function normalizeParticipantContextField(field = {}, index = 0) {
|
|
42
|
-
return {
|
|
43
|
-
fieldId: normalizeText(field.fieldId, `field_${index + 1}`),
|
|
44
|
-
label: normalizeText(field.label, `Field ${index + 1}`),
|
|
45
|
-
type: normalizeText(field.type, 'string'),
|
|
46
|
-
required: typeof field.required === 'boolean' ? field.required : null,
|
|
47
|
-
searchable: typeof field.searchable === 'boolean' ? field.searchable : null,
|
|
48
|
-
description: normalizeText(field.description, null),
|
|
49
|
-
examples: normalizeStringList(field.examples),
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function normalizeParticipantContextFieldPayload(field = null) {
|
|
54
|
-
if (!field || typeof field !== 'object' || Array.isArray(field)) return null;
|
|
55
|
-
return normalizeParticipantContextField(field);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function normalizeWorldStats(stats = null) {
|
|
59
|
-
if (!stats || typeof stats !== 'object' || Array.isArray(stats)) return null;
|
|
60
|
-
return {
|
|
61
|
-
totalParticipants: normalizeOptionalInteger(stats.totalParticipants, null),
|
|
62
|
-
activeParticipants: normalizeOptionalInteger(stats.activeParticipants, null),
|
|
63
|
-
totalConversationCount: normalizeOptionalInteger(stats.totalConversationCount, null),
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function normalizeWorldRole(worldRole, fallback = null) {
|
|
68
|
-
const normalized = normalizeText(worldRole, fallback);
|
|
69
|
-
return ['owner', 'member'].includes(normalized) ? normalized : fallback;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function normalizeBroadcastAudience(value, fallback = 'members') {
|
|
73
|
-
const normalized = normalizeText(value, fallback);
|
|
74
|
-
if (normalized === 'admins') return 'admins';
|
|
75
|
-
if (normalized === 'admins_and_owner') return 'admins_and_owner';
|
|
76
|
-
return 'members';
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function normalizeBroadcastReplyPolicy(value, fallback = 'zero') {
|
|
80
|
-
const normalized = normalizeText(value, fallback);
|
|
81
|
-
if (normalized === 'at_most_one') return 'at_most_one';
|
|
82
|
-
return 'zero';
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function normalizeWorldBroadcastConfig(broadcast = null) {
|
|
86
|
-
if (!broadcast || typeof broadcast !== 'object' || Array.isArray(broadcast)) return null;
|
|
87
|
-
return {
|
|
88
|
-
enabled: normalizeOptionalBoolean(broadcast.enabled, null),
|
|
89
|
-
audience: normalizeBroadcastAudience(broadcast.audience, 'members'),
|
|
90
|
-
replyPolicy: normalizeBroadcastReplyPolicy(broadcast.replyPolicy, 'zero'),
|
|
91
|
-
excludeSelf: normalizeOptionalBoolean(broadcast.excludeSelf, null),
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function normalizeManagedWorld(payload = {}) {
|
|
96
|
-
return {
|
|
97
|
-
worldId: normalizeText(payload.worldId, null),
|
|
98
|
-
displayName: normalizeText(payload.displayName, null),
|
|
99
|
-
worldContextText: normalizeText(payload.worldContextText, null),
|
|
100
|
-
ownerAgentId: normalizeText(payload.ownerAgentId, null),
|
|
101
|
-
enabled: normalizeOptionalBoolean(payload.enabled, null),
|
|
102
|
-
status: normalizeText(payload.status, null),
|
|
103
|
-
worldRole: normalizeWorldRole(payload.worldRole, null),
|
|
104
|
-
schemaVersion: normalizeOptionalInteger(payload.schemaVersion, null),
|
|
105
|
-
createdAt: normalizeText(payload.createdAt, null),
|
|
106
|
-
updatedAt: normalizeText(payload.updatedAt, null),
|
|
107
|
-
participantContextField: normalizeParticipantContextFieldPayload(payload.participantContextField),
|
|
108
|
-
broadcast: normalizeWorldBroadcastConfig(payload.broadcast),
|
|
109
|
-
stats: normalizeWorldStats(payload.stats),
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function normalizeCreatedWorld(payload = {}) {
|
|
114
|
-
const world = normalizeManagedWorld(payload);
|
|
115
|
-
return {
|
|
116
|
-
...world,
|
|
117
|
-
ownerJoin:
|
|
118
|
-
payload.ownerJoin && typeof payload.ownerJoin === 'object'
|
|
119
|
-
? normalizeWorldJoinResponse(payload.ownerJoin, {
|
|
120
|
-
worldId: world.worldId,
|
|
121
|
-
agentId: world.ownerAgentId,
|
|
122
|
-
})
|
|
123
|
-
: null,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function normalizeOwnedWorldSummary(payload = {}) {
|
|
128
|
-
return {
|
|
129
|
-
worldId: normalizeText(payload.worldId, null),
|
|
130
|
-
displayName: normalizeText(payload.displayName, null),
|
|
131
|
-
worldContextText: normalizeText(payload.worldContextText, null),
|
|
132
|
-
ownerAgentId: normalizeText(payload.ownerAgentId, null),
|
|
133
|
-
enabled: normalizeOptionalBoolean(payload.enabled, null),
|
|
134
|
-
status: normalizeText(payload.status, null),
|
|
135
|
-
worldRole: normalizeWorldRole(payload.worldRole, null),
|
|
136
|
-
createdAt: normalizeText(payload.createdAt, null),
|
|
137
|
-
updatedAt: normalizeText(payload.updatedAt, null),
|
|
138
|
-
broadcast: normalizeWorldBroadcastConfig(payload.broadcast),
|
|
139
|
-
stats: normalizeWorldStats(payload.stats),
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function normalizeWorldBroadcastRequestItem(item = {}) {
|
|
144
|
-
return {
|
|
145
|
-
agentId: normalizeText(item.agentId, null),
|
|
146
|
-
status: normalizeText(item.status, null),
|
|
147
|
-
verdict: normalizeText(item.verdict, null),
|
|
148
|
-
chatRequest: item.chatRequest && typeof item.chatRequest === 'object' && !Array.isArray(item.chatRequest)
|
|
149
|
-
? item.chatRequest
|
|
150
|
-
: null,
|
|
151
|
-
kickoff: item.kickoff && typeof item.kickoff === 'object' && !Array.isArray(item.kickoff)
|
|
152
|
-
? item.kickoff
|
|
153
|
-
: null,
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function normalizeWorldBroadcastFailureItem(item = {}) {
|
|
158
|
-
return {
|
|
159
|
-
agentId: normalizeText(item.agentId, null),
|
|
160
|
-
status: normalizeText(item.status, 'failed'),
|
|
161
|
-
httpStatus: normalizeOptionalInteger(item.httpStatus, null),
|
|
162
|
-
error: normalizeText(item.error, null),
|
|
163
|
-
reason: normalizeText(item.reason, null),
|
|
164
|
-
message: normalizeText(item.message, null),
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function normalizeWorldBroadcastResponse(payload = {}) {
|
|
169
|
-
return {
|
|
170
|
-
status: normalizeText(payload.status, null),
|
|
171
|
-
worldId: normalizeText(payload.worldId, null),
|
|
172
|
-
senderAgentId: normalizeText(payload.senderAgentId, null),
|
|
173
|
-
senderRole: normalizeWorldRole(payload.senderRole, null),
|
|
174
|
-
audience: normalizeBroadcastAudience(payload.audience, 'members'),
|
|
175
|
-
excludeSelf: normalizeOptionalBoolean(payload.excludeSelf, null),
|
|
176
|
-
eligibility: normalizeText(payload.eligibility, null),
|
|
177
|
-
broadcastId: normalizeText(payload.broadcastId, null),
|
|
178
|
-
totalTargets: normalizeOptionalInteger(payload.totalTargets, null),
|
|
179
|
-
createdCount: normalizeOptionalInteger(payload.createdCount, null),
|
|
180
|
-
failedCount: normalizeOptionalInteger(payload.failedCount, null),
|
|
181
|
-
pendingCount: normalizeOptionalInteger(payload.pendingCount, null),
|
|
182
|
-
autoAcceptedCount: normalizeOptionalInteger(payload.autoAcceptedCount, null),
|
|
183
|
-
rejectedCount: normalizeOptionalInteger(payload.rejectedCount, null),
|
|
184
|
-
nextAction: normalizeText(payload.nextAction, null),
|
|
185
|
-
requests: Array.isArray(payload.requests)
|
|
186
|
-
? payload.requests.map((item) => normalizeWorldBroadcastRequestItem(item))
|
|
187
|
-
: [],
|
|
188
|
-
failures: Array.isArray(payload.failures)
|
|
189
|
-
? payload.failures.map((item) => normalizeWorldBroadcastFailureItem(item))
|
|
190
|
-
: [],
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
async function fetchJson(fetchImpl, url, init = {}) {
|
|
195
|
-
let response;
|
|
196
|
-
try {
|
|
197
|
-
response = await fetchImpl(url, init);
|
|
198
|
-
} catch (error) {
|
|
199
|
-
throw createRuntimeBoundaryError({
|
|
200
|
-
code: 'relay_fetch_failed',
|
|
201
|
-
category: 'transport',
|
|
202
|
-
status: 502,
|
|
203
|
-
message: `fetch failed: ${error?.message || String(error)}`,
|
|
204
|
-
publicMessage: 'relay fetch failed',
|
|
205
|
-
recoverable: true,
|
|
206
|
-
context: {
|
|
207
|
-
fetchUrl: url,
|
|
208
|
-
fetchMethod: init?.method || 'GET',
|
|
209
|
-
},
|
|
210
|
-
cause: error,
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
let body = null;
|
|
214
|
-
try {
|
|
215
|
-
body = await response.json();
|
|
216
|
-
} catch {
|
|
217
|
-
body = null;
|
|
218
|
-
}
|
|
219
|
-
return { ok: response.ok, status: response.status, body };
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
function normalizeRelayHttpBaseUrl(serverUrl) {
|
|
223
|
-
const parsed = new URL(serverUrl);
|
|
224
|
-
if (parsed.protocol === 'ws:') parsed.protocol = 'http:';
|
|
225
|
-
if (parsed.protocol === 'wss:') parsed.protocol = 'https:';
|
|
226
|
-
parsed.pathname = '';
|
|
227
|
-
parsed.search = '';
|
|
228
|
-
parsed.hash = '';
|
|
229
|
-
return parsed.toString().replace(/\/$/, '');
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function inferHttpErrorCategory(status) {
|
|
233
|
-
if (status === 401) return 'auth';
|
|
234
|
-
if (status === 403) return 'policy';
|
|
235
|
-
if (status === 409) return 'conflict';
|
|
236
|
-
if (status >= 400 && status < 500) return 'input';
|
|
237
|
-
return 'runtime';
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
function createModerationHttpError(action, response, { accountId = null, worldId = null } = {}) {
|
|
241
|
-
const backendCode = normalizeText(response?.body?.error, null);
|
|
242
|
-
const backendMessage = normalizeText(response?.body?.message, `claworld world ${action} failed`);
|
|
243
|
-
|
|
244
|
-
return createRuntimeBoundaryError({
|
|
245
|
-
code: backendCode || `claworld_world_${action}_failed`,
|
|
246
|
-
category: inferHttpErrorCategory(response?.status),
|
|
247
|
-
status: response?.status ?? 500,
|
|
248
|
-
message: `claworld world ${action} failed: ${response?.status ?? 500}`,
|
|
249
|
-
publicMessage: backendMessage,
|
|
250
|
-
recoverable: Number(response?.status) >= 400 && Number(response?.status) < 500,
|
|
251
|
-
context: {
|
|
252
|
-
action: `world_${action}`,
|
|
253
|
-
accountId,
|
|
254
|
-
...(worldId ? { worldId } : {}),
|
|
255
|
-
httpStatus: response?.status ?? 500,
|
|
256
|
-
...extractBackendErrorContext(response?.body),
|
|
257
|
-
},
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
export async function createModeratedWorld({
|
|
262
|
-
cfg = {},
|
|
263
|
-
accountId = null,
|
|
264
|
-
runtimeConfig = null,
|
|
265
|
-
agentId = null,
|
|
266
|
-
displayName = null,
|
|
267
|
-
worldContextText = null,
|
|
268
|
-
participantContextText = null,
|
|
269
|
-
enabled = true,
|
|
270
|
-
fetchImpl,
|
|
271
|
-
logger = console,
|
|
272
|
-
} = {}) {
|
|
273
|
-
if (typeof fetchImpl !== 'function') {
|
|
274
|
-
throw new Error('fetch is unavailable for claworld world creation helper');
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
const resolvedAgentId = normalizeText(agentId, null);
|
|
278
|
-
if (!resolvedAgentId) {
|
|
279
|
-
throw new Error('claworld world creation helper requires agentId');
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
|
|
283
|
-
const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
|
|
284
|
-
const created = await fetchJson(fetchImpl, `${baseUrl}/v1/worlds`, {
|
|
285
|
-
method: 'POST',
|
|
286
|
-
headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
|
|
287
|
-
accept: 'application/json',
|
|
288
|
-
'content-type': 'application/json',
|
|
289
|
-
...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
|
|
290
|
-
}),
|
|
291
|
-
body: JSON.stringify({
|
|
292
|
-
agentId: resolvedAgentId,
|
|
293
|
-
displayName,
|
|
294
|
-
worldContextText,
|
|
295
|
-
participantContextText: normalizeText(participantContextText, null),
|
|
296
|
-
enabled,
|
|
297
|
-
}),
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
if (!created.ok) {
|
|
301
|
-
logger.error?.('[claworld:moderation] world create failed', {
|
|
302
|
-
status: created.status,
|
|
303
|
-
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
304
|
-
body: created.body,
|
|
305
|
-
});
|
|
306
|
-
throw createModerationHttpError('create', created, {
|
|
307
|
-
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
return normalizeCreatedWorld(created.body);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
export async function fetchOwnedWorlds({
|
|
315
|
-
cfg = {},
|
|
316
|
-
accountId = null,
|
|
317
|
-
runtimeConfig = null,
|
|
318
|
-
agentId = null,
|
|
319
|
-
includeDisabled = true,
|
|
320
|
-
fetchImpl,
|
|
321
|
-
logger = console,
|
|
322
|
-
} = {}) {
|
|
323
|
-
if (typeof fetchImpl !== 'function') {
|
|
324
|
-
throw new Error('fetch is unavailable for claworld owned-worlds helper');
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
const resolvedAgentId = normalizeText(agentId, null);
|
|
328
|
-
if (!resolvedAgentId) {
|
|
329
|
-
throw new Error('claworld owned-worlds helper requires agentId');
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
|
|
333
|
-
const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
|
|
334
|
-
const requestUrl = new URL(`${baseUrl}/v1/moderation/worlds`);
|
|
335
|
-
requestUrl.searchParams.set('agentId', resolvedAgentId);
|
|
336
|
-
requestUrl.searchParams.set('includeDisabled', includeDisabled ? 'true' : 'false');
|
|
337
|
-
const result = await fetchJson(fetchImpl, requestUrl.toString(), {
|
|
338
|
-
headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
|
|
339
|
-
accept: 'application/json',
|
|
340
|
-
...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
|
|
341
|
-
}),
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
if (!result.ok) {
|
|
345
|
-
logger.error?.('[claworld:moderation] managed worlds fetch failed', {
|
|
346
|
-
status: result.status,
|
|
347
|
-
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
348
|
-
body: result.body,
|
|
349
|
-
});
|
|
350
|
-
throw createModerationHttpError('list', result, {
|
|
351
|
-
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
return {
|
|
356
|
-
items: Array.isArray(result.body?.items) ? result.body.items.map((item) => normalizeOwnedWorldSummary(item)) : [],
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
export async function manageModeratedWorld({
|
|
361
|
-
cfg = {},
|
|
362
|
-
accountId = null,
|
|
363
|
-
runtimeConfig = null,
|
|
364
|
-
agentId = null,
|
|
365
|
-
worldId = null,
|
|
366
|
-
mode = 'get',
|
|
367
|
-
changes = null,
|
|
368
|
-
enabled = null,
|
|
369
|
-
status = null,
|
|
370
|
-
fetchImpl,
|
|
371
|
-
logger = console,
|
|
372
|
-
} = {}) {
|
|
373
|
-
if (typeof fetchImpl !== 'function') {
|
|
374
|
-
throw new Error('fetch is unavailable for claworld world management helper');
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
const resolvedAgentId = normalizeText(agentId, null);
|
|
378
|
-
if (!resolvedAgentId) {
|
|
379
|
-
throw new Error('claworld world management helper requires agentId');
|
|
380
|
-
}
|
|
381
|
-
const resolvedWorldId = normalizeText(worldId, null);
|
|
382
|
-
if (!resolvedWorldId) {
|
|
383
|
-
throw new Error('claworld world management helper requires worldId');
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
|
|
387
|
-
const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
|
|
388
|
-
|
|
389
|
-
if (normalizeText(mode, 'get') === 'get') {
|
|
390
|
-
const requestUrl = new URL(`${baseUrl}/v1/moderation/worlds/${encodeURIComponent(resolvedWorldId)}`);
|
|
391
|
-
requestUrl.searchParams.set('agentId', resolvedAgentId);
|
|
392
|
-
const result = await fetchJson(fetchImpl, requestUrl.toString(), {
|
|
393
|
-
headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
|
|
394
|
-
accept: 'application/json',
|
|
395
|
-
...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
|
|
396
|
-
}),
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
if (!result.ok) {
|
|
400
|
-
logger.error?.('[claworld:moderation] managed world fetch failed', {
|
|
401
|
-
status: result.status,
|
|
402
|
-
worldId: resolvedWorldId,
|
|
403
|
-
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
404
|
-
body: result.body,
|
|
405
|
-
});
|
|
406
|
-
throw createModerationHttpError('get', result, {
|
|
407
|
-
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
408
|
-
worldId: resolvedWorldId,
|
|
409
|
-
});
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
return normalizeManagedWorld(result.body);
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
const result = await fetchJson(fetchImpl, `${baseUrl}/v1/moderation/worlds/${encodeURIComponent(resolvedWorldId)}`, {
|
|
416
|
-
method: 'PATCH',
|
|
417
|
-
headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
|
|
418
|
-
accept: 'application/json',
|
|
419
|
-
'content-type': 'application/json',
|
|
420
|
-
...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
|
|
421
|
-
}),
|
|
422
|
-
body: JSON.stringify({
|
|
423
|
-
agentId: resolvedAgentId,
|
|
424
|
-
...(changes && typeof changes === 'object' ? { changes } : {}),
|
|
425
|
-
...(enabled == null ? {} : { enabled }),
|
|
426
|
-
...(normalizeText(status, null) ? { status: normalizeText(status, null) } : {}),
|
|
427
|
-
}),
|
|
428
|
-
});
|
|
429
|
-
|
|
430
|
-
if (!result.ok) {
|
|
431
|
-
logger.error?.('[claworld:moderation] managed world update failed', {
|
|
432
|
-
status: result.status,
|
|
433
|
-
worldId: resolvedWorldId,
|
|
434
|
-
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
435
|
-
body: result.body,
|
|
436
|
-
});
|
|
437
|
-
throw createModerationHttpError('update', result, {
|
|
438
|
-
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
439
|
-
worldId: resolvedWorldId,
|
|
440
|
-
});
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
return normalizeManagedWorld(result.body);
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
export async function broadcastModeratedWorld({
|
|
447
|
-
cfg = {},
|
|
448
|
-
accountId = null,
|
|
449
|
-
runtimeConfig = null,
|
|
450
|
-
agentId = null,
|
|
451
|
-
worldId = null,
|
|
452
|
-
announcementText = null,
|
|
453
|
-
audience = null,
|
|
454
|
-
excludeSelf = null,
|
|
455
|
-
fetchImpl,
|
|
456
|
-
logger = console,
|
|
457
|
-
} = {}) {
|
|
458
|
-
if (typeof fetchImpl !== 'function') {
|
|
459
|
-
throw new Error('fetch is unavailable for claworld world broadcast helper');
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
const resolvedAgentId = normalizeText(agentId, null);
|
|
463
|
-
if (!resolvedAgentId) {
|
|
464
|
-
throw new Error('claworld world broadcast helper requires agentId');
|
|
465
|
-
}
|
|
466
|
-
const resolvedWorldId = normalizeText(worldId, null);
|
|
467
|
-
if (!resolvedWorldId) {
|
|
468
|
-
throw new Error('claworld world broadcast helper requires worldId');
|
|
469
|
-
}
|
|
470
|
-
const resolvedAnnouncementText = normalizeText(announcementText, null);
|
|
471
|
-
if (!resolvedAnnouncementText) {
|
|
472
|
-
throw new Error('claworld world broadcast helper requires announcementText');
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
|
|
476
|
-
const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
|
|
477
|
-
const result = await fetchJson(fetchImpl, `${baseUrl}/v1/worlds/${encodeURIComponent(resolvedWorldId)}/broadcast`, {
|
|
478
|
-
method: 'POST',
|
|
479
|
-
headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
|
|
480
|
-
accept: 'application/json',
|
|
481
|
-
'content-type': 'application/json',
|
|
482
|
-
...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
|
|
483
|
-
}),
|
|
484
|
-
body: JSON.stringify({
|
|
485
|
-
agentId: resolvedAgentId,
|
|
486
|
-
payload: {
|
|
487
|
-
text: resolvedAnnouncementText,
|
|
488
|
-
},
|
|
489
|
-
...(normalizeText(audience, null) ? { audience: normalizeText(audience, null) } : {}),
|
|
490
|
-
...(typeof excludeSelf === 'boolean' ? { excludeSelf } : {}),
|
|
491
|
-
}),
|
|
492
|
-
});
|
|
493
|
-
|
|
494
|
-
if (!result.ok) {
|
|
495
|
-
logger.error?.('[claworld:moderation] world broadcast failed', {
|
|
496
|
-
status: result.status,
|
|
497
|
-
worldId: resolvedWorldId,
|
|
498
|
-
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
499
|
-
body: result.body,
|
|
500
|
-
});
|
|
501
|
-
throw createModerationHttpError('broadcast', result, {
|
|
502
|
-
accountId: resolvedRuntimeConfig.accountId || accountId || null,
|
|
503
|
-
worldId: resolvedWorldId,
|
|
504
|
-
});
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
return normalizeWorldBroadcastResponse(result.body);
|
|
508
|
-
}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
const DEFAULT_MODE = 'open';
|
|
2
|
-
const SUPPORTED_MODES = Object.freeze([
|
|
3
|
-
'manual_review',
|
|
4
|
-
'world_only',
|
|
5
|
-
'trusted_only',
|
|
6
|
-
'trusted_or_world',
|
|
7
|
-
'open',
|
|
8
|
-
]);
|
|
9
|
-
const SUPPORTED_ORIGIN_TYPES = Object.freeze([
|
|
10
|
-
'chat_request',
|
|
11
|
-
'world_broadcast',
|
|
12
|
-
]);
|
|
13
|
-
|
|
14
|
-
function normalizeText(value, fallback = null) {
|
|
15
|
-
if (value == null) return fallback;
|
|
16
|
-
const normalized = String(value).trim();
|
|
17
|
-
return normalized || fallback;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function normalizeToken(value, fallback = null) {
|
|
21
|
-
const normalized = normalizeText(value, fallback);
|
|
22
|
-
return normalized ? normalized.toLowerCase().replace(/[\s-]+/g, '_') : fallback;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function uniqueStrings(values = [], normalizer = (value) => normalizeText(value, null)) {
|
|
26
|
-
const seen = new Set();
|
|
27
|
-
const items = [];
|
|
28
|
-
for (const value of Array.isArray(values) ? values : []) {
|
|
29
|
-
const normalized = normalizer(value);
|
|
30
|
-
if (!normalized || seen.has(normalized)) continue;
|
|
31
|
-
seen.add(normalized);
|
|
32
|
-
items.push(normalized);
|
|
33
|
-
}
|
|
34
|
-
return items;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export const CHAT_REQUEST_APPROVAL_POLICY_SCHEMA_VERSION = 1;
|
|
38
|
-
export const CHAT_REQUEST_APPROVAL_POLICY_MODES = SUPPORTED_MODES;
|
|
39
|
-
export const CHAT_REQUEST_APPROVAL_POLICY_ORIGIN_TYPES = SUPPORTED_ORIGIN_TYPES;
|
|
40
|
-
export const DEFAULT_CHAT_REQUEST_APPROVAL_POLICY_MODE = DEFAULT_MODE;
|
|
41
|
-
|
|
42
|
-
export function normalizeChatRequestApprovalMode(value, fallback = DEFAULT_MODE) {
|
|
43
|
-
const normalized = normalizeToken(value, null);
|
|
44
|
-
switch (normalized) {
|
|
45
|
-
case 'manual':
|
|
46
|
-
case 'manual_review':
|
|
47
|
-
case 'review':
|
|
48
|
-
return 'manual_review';
|
|
49
|
-
case 'world':
|
|
50
|
-
case 'world_only':
|
|
51
|
-
return 'world_only';
|
|
52
|
-
case 'trusted':
|
|
53
|
-
case 'trusted_only':
|
|
54
|
-
return 'trusted_only';
|
|
55
|
-
case 'trusted_or_world':
|
|
56
|
-
case 'world_or_trusted':
|
|
57
|
-
return 'trusted_or_world';
|
|
58
|
-
case 'open':
|
|
59
|
-
case 'auto_accept':
|
|
60
|
-
case 'all':
|
|
61
|
-
return 'open';
|
|
62
|
-
default:
|
|
63
|
-
return SUPPORTED_MODES.includes(fallback) ? fallback : DEFAULT_MODE;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export function normalizeChatRequestApprovalOriginType(value, fallback = null) {
|
|
68
|
-
const normalized = normalizeToken(value, fallback);
|
|
69
|
-
return SUPPORTED_ORIGIN_TYPES.includes(normalized) ? normalized : fallback;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export function normalizeChatRequestApprovalBlocks(value = {}) {
|
|
73
|
-
const candidate = value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
74
|
-
return {
|
|
75
|
-
originTypes: uniqueStrings(candidate.originTypes, (entry) => normalizeChatRequestApprovalOriginType(entry, null)).sort(),
|
|
76
|
-
worldIds: uniqueStrings(candidate.worldIds, (entry) => normalizeText(entry, null)).sort(),
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export function normalizeChatRequestApprovalPolicy(
|
|
81
|
-
value = {},
|
|
82
|
-
{ fallbackMode = DEFAULT_MODE } = {},
|
|
83
|
-
) {
|
|
84
|
-
const candidate = value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
85
|
-
const mode = normalizeText(candidate.mode, null)
|
|
86
|
-
? normalizeChatRequestApprovalMode(candidate.mode, fallbackMode)
|
|
87
|
-
: normalizeChatRequestApprovalMode(fallbackMode, DEFAULT_MODE);
|
|
88
|
-
|
|
89
|
-
return {
|
|
90
|
-
mode,
|
|
91
|
-
blocks: normalizeChatRequestApprovalBlocks(candidate.blocks),
|
|
92
|
-
};
|
|
93
|
-
}
|