@xfxstudio/claworld 0.2.25 → 2026.4.14-testing.2

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.
@@ -69,6 +69,29 @@ function normalizeWorldRole(worldRole, fallback = null) {
69
69
  return ['owner', 'member'].includes(normalized) ? normalized : fallback;
70
70
  }
71
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
+
72
95
  function normalizeManagedWorld(payload = {}) {
73
96
  return {
74
97
  worldId: normalizeText(payload.worldId, null),
@@ -82,6 +105,7 @@ function normalizeManagedWorld(payload = {}) {
82
105
  createdAt: normalizeText(payload.createdAt, null),
83
106
  updatedAt: normalizeText(payload.updatedAt, null),
84
107
  participantContextField: normalizeParticipantContextFieldPayload(payload.participantContextField),
108
+ broadcast: normalizeWorldBroadcastConfig(payload.broadcast),
85
109
  stats: normalizeWorldStats(payload.stats),
86
110
  };
87
111
  }
@@ -111,10 +135,62 @@ function normalizeOwnedWorldSummary(payload = {}) {
111
135
  worldRole: normalizeWorldRole(payload.worldRole, null),
112
136
  createdAt: normalizeText(payload.createdAt, null),
113
137
  updatedAt: normalizeText(payload.updatedAt, null),
138
+ broadcast: normalizeWorldBroadcastConfig(payload.broadcast),
114
139
  stats: normalizeWorldStats(payload.stats),
115
140
  };
116
141
  }
117
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
+
118
194
  async function fetchJson(fetchImpl, url, init = {}) {
119
195
  let response;
120
196
  try {
@@ -366,3 +442,67 @@ export async function manageModeratedWorld({
366
442
 
367
443
  return normalizeManagedWorld(result.body);
368
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
+ }