@xfxstudio/claworld 0.2.22 → 0.2.23-beta.0
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
CHANGED
package/package.json
CHANGED
|
@@ -1328,6 +1328,30 @@ function createDeliveryReplyDispatcher({
|
|
|
1328
1328
|
runtimeOutputSummary.counts[kind] += 1;
|
|
1329
1329
|
};
|
|
1330
1330
|
|
|
1331
|
+
const submitRelayReply = async (replyText) => {
|
|
1332
|
+
if (typeof relayClient?.submitDeliveryReply !== 'function') {
|
|
1333
|
+
throw new Error('relay client does not support reply submission');
|
|
1334
|
+
}
|
|
1335
|
+
return await relayClient.submitDeliveryReply({
|
|
1336
|
+
deliveryId,
|
|
1337
|
+
sessionKey,
|
|
1338
|
+
replyText,
|
|
1339
|
+
source: 'openclaw-autochain',
|
|
1340
|
+
});
|
|
1341
|
+
};
|
|
1342
|
+
|
|
1343
|
+
const submitRelayKeptSilent = async (reason) => {
|
|
1344
|
+
if (typeof relayClient?.submitDeliveryKeptSilent !== 'function') {
|
|
1345
|
+
throw new Error('relay client does not support kept_silent submission');
|
|
1346
|
+
}
|
|
1347
|
+
return await relayClient.submitDeliveryKeptSilent({
|
|
1348
|
+
deliveryId,
|
|
1349
|
+
sessionKey,
|
|
1350
|
+
reason,
|
|
1351
|
+
source: 'openclaw-autochain',
|
|
1352
|
+
});
|
|
1353
|
+
};
|
|
1354
|
+
|
|
1331
1355
|
const flushReply = async (text) => {
|
|
1332
1356
|
const normalized = String(text || '').trim();
|
|
1333
1357
|
if (!normalized || replied || suppressed) return false;
|
|
@@ -1335,25 +1359,9 @@ function createDeliveryReplyDispatcher({
|
|
|
1335
1359
|
suppressed = true;
|
|
1336
1360
|
return false;
|
|
1337
1361
|
}
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
sessionKey,
|
|
1342
|
-
replyText: normalized,
|
|
1343
|
-
source: 'openclaw-autochain',
|
|
1344
|
-
});
|
|
1345
|
-
replyTransport = replyResult?.transport || 'websocket';
|
|
1346
|
-
replyFallbackUsed = replyResult?.fallbackUsed === true;
|
|
1347
|
-
} else {
|
|
1348
|
-
relayClient.sendReply({
|
|
1349
|
-
deliveryId,
|
|
1350
|
-
sessionKey,
|
|
1351
|
-
replyText: normalized,
|
|
1352
|
-
source: 'openclaw-autochain',
|
|
1353
|
-
});
|
|
1354
|
-
replyTransport = 'websocket-fire-and-forget';
|
|
1355
|
-
replyFallbackUsed = false;
|
|
1356
|
-
}
|
|
1362
|
+
const replyResult = await submitRelayReply(normalized);
|
|
1363
|
+
replyTransport = replyResult?.transport || null;
|
|
1364
|
+
replyFallbackUsed = replyResult?.fallbackUsed === true;
|
|
1357
1365
|
replied = true;
|
|
1358
1366
|
return true;
|
|
1359
1367
|
};
|
|
@@ -1364,19 +1372,11 @@ function createDeliveryReplyDispatcher({
|
|
|
1364
1372
|
suppressed = true;
|
|
1365
1373
|
return false;
|
|
1366
1374
|
}
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
source: 'openclaw-autochain',
|
|
1373
|
-
});
|
|
1374
|
-
keptSilentTransport = silentResult?.transport || 'websocket';
|
|
1375
|
-
keptSilentFallbackUsed = silentResult?.fallbackUsed === true;
|
|
1376
|
-
} else {
|
|
1377
|
-
keptSilentTransport = 'unsupported';
|
|
1378
|
-
keptSilentFallbackUsed = false;
|
|
1379
|
-
}
|
|
1375
|
+
const silentResult = await submitRelayKeptSilent(
|
|
1376
|
+
normalizePluginOptionalText(reason) || 'no_renderable_reply',
|
|
1377
|
+
);
|
|
1378
|
+
keptSilentTransport = silentResult?.transport || null;
|
|
1379
|
+
keptSilentFallbackUsed = silentResult?.fallbackUsed === true;
|
|
1380
1380
|
keptSilent = true;
|
|
1381
1381
|
return true;
|
|
1382
1382
|
};
|
|
@@ -1709,12 +1709,13 @@ async function maybeBridgeRuntimeDelivery({
|
|
|
1709
1709
|
});
|
|
1710
1710
|
|
|
1711
1711
|
try {
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1712
|
+
const acceptedResult = await relayClient.acceptDeliveryHttp({
|
|
1713
|
+
deliveryId,
|
|
1714
|
+
sessionKey,
|
|
1715
|
+
source: 'runtime_dispatch',
|
|
1716
|
+
});
|
|
1717
|
+
if (acceptedResult.status < 200 || acceptedResult.status >= 300) {
|
|
1718
|
+
throw new Error(`failed to submit relay delivery acceptance: ${acceptedResult.status}`);
|
|
1718
1719
|
}
|
|
1719
1720
|
} catch (error) {
|
|
1720
1721
|
logger.warn?.(`[claworld:${runtimeAccountId}] delivery acceptance acknowledgement failed`, {
|
|
@@ -29,6 +29,21 @@ import {
|
|
|
29
29
|
TERMINAL_CLOSE_REASONS,
|
|
30
30
|
} from './relay-client-shared.js';
|
|
31
31
|
|
|
32
|
+
const DELIVERY_VISIBILITY_RETRY_ATTEMPTS = 20;
|
|
33
|
+
const DELIVERY_VISIBILITY_RETRY_DELAY_MS = 10;
|
|
34
|
+
|
|
35
|
+
function isDeliveryVisibilityMiss(result = {}) {
|
|
36
|
+
return Number(result?.status) === 404
|
|
37
|
+
&& normalizeOptionalText(result?.body?.error) === 'delivery_not_found';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function waitForDeliveryVisibilityRetry() {
|
|
41
|
+
await new Promise((resolve) => {
|
|
42
|
+
const timer = setTimeout(resolve, DELIVERY_VISIBILITY_RETRY_DELAY_MS);
|
|
43
|
+
if (typeof timer?.unref === 'function') timer.unref();
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
32
47
|
export class ClaworldRelayClient extends EventEmitter {
|
|
33
48
|
constructor({
|
|
34
49
|
logger = console,
|
|
@@ -244,6 +259,18 @@ export class ClaworldRelayClient extends EventEmitter {
|
|
|
244
259
|
return { status: response.status, body };
|
|
245
260
|
}
|
|
246
261
|
|
|
262
|
+
async requestJsonWithDeliveryVisibilityRetry(pathName, init = {}, fallback = {}) {
|
|
263
|
+
let attempt = 0;
|
|
264
|
+
while (true) {
|
|
265
|
+
const result = await this.requestJson(pathName, init, fallback);
|
|
266
|
+
if (!isDeliveryVisibilityMiss(result) || attempt >= DELIVERY_VISIBILITY_RETRY_ATTEMPTS - 1) {
|
|
267
|
+
return result;
|
|
268
|
+
}
|
|
269
|
+
attempt += 1;
|
|
270
|
+
await waitForDeliveryVisibilityRetry();
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
247
274
|
async openSocket({
|
|
248
275
|
wsUrl,
|
|
249
276
|
agentId,
|
|
@@ -879,7 +906,7 @@ export class ClaworldRelayClient extends EventEmitter {
|
|
|
879
906
|
replyText,
|
|
880
907
|
source,
|
|
881
908
|
});
|
|
882
|
-
const result = await this.
|
|
909
|
+
const result = await this.requestJsonWithDeliveryVisibilityRetry(`/v1/deliveries/${encodeURIComponent(envelope.deliveryId)}/reply`, {
|
|
883
910
|
method: 'POST',
|
|
884
911
|
headers: buildRuntimeAuthHeaders(this.runtimeConfig, { 'content-type': 'application/json' }),
|
|
885
912
|
body: JSON.stringify({
|
|
@@ -901,7 +928,7 @@ export class ClaworldRelayClient extends EventEmitter {
|
|
|
901
928
|
|
|
902
929
|
async acceptDeliveryHttp({ deliveryId, sessionKey = null, source = 'runtime_dispatch' } = {}) {
|
|
903
930
|
const normalizedDeliveryId = normalizeOptionalText(deliveryId);
|
|
904
|
-
const result = await this.
|
|
931
|
+
const result = await this.requestJsonWithDeliveryVisibilityRetry(`/v1/deliveries/${encodeURIComponent(normalizedDeliveryId)}/accepted`, {
|
|
905
932
|
method: 'POST',
|
|
906
933
|
headers: buildRuntimeAuthHeaders(this.runtimeConfig, { 'content-type': 'application/json' }),
|
|
907
934
|
body: JSON.stringify({
|
|
@@ -932,6 +959,10 @@ export class ClaworldRelayClient extends EventEmitter {
|
|
|
932
959
|
timeoutMs = DEFAULT_REPLY_ACK_TIMEOUT_MS,
|
|
933
960
|
httpFallback = true,
|
|
934
961
|
} = {}) {
|
|
962
|
+
const ackPromise = this.waitForReplyAck({
|
|
963
|
+
deliveryId,
|
|
964
|
+
timeoutMs,
|
|
965
|
+
});
|
|
935
966
|
const envelope = this.sendReply({
|
|
936
967
|
deliveryId,
|
|
937
968
|
sessionKey,
|
|
@@ -940,10 +971,7 @@ export class ClaworldRelayClient extends EventEmitter {
|
|
|
940
971
|
});
|
|
941
972
|
|
|
942
973
|
try {
|
|
943
|
-
const ack = await
|
|
944
|
-
deliveryId: envelope.deliveryId,
|
|
945
|
-
timeoutMs,
|
|
946
|
-
});
|
|
974
|
+
const ack = await ackPromise;
|
|
947
975
|
return {
|
|
948
976
|
ok: true,
|
|
949
977
|
envelope,
|
|
@@ -1011,6 +1039,24 @@ export class ClaworldRelayClient extends EventEmitter {
|
|
|
1011
1039
|
}
|
|
1012
1040
|
}
|
|
1013
1041
|
|
|
1042
|
+
async submitDeliveryReply({
|
|
1043
|
+
deliveryId,
|
|
1044
|
+
sessionKey,
|
|
1045
|
+
replyText,
|
|
1046
|
+
source = 'subagent',
|
|
1047
|
+
timeoutMs = DEFAULT_REPLY_ACK_TIMEOUT_MS,
|
|
1048
|
+
httpFallback = true,
|
|
1049
|
+
} = {}) {
|
|
1050
|
+
return await this.sendReplyAndWaitForAck({
|
|
1051
|
+
deliveryId,
|
|
1052
|
+
sessionKey,
|
|
1053
|
+
replyText,
|
|
1054
|
+
source,
|
|
1055
|
+
timeoutMs,
|
|
1056
|
+
httpFallback,
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1014
1060
|
async sendAcceptedAndWaitForAck({
|
|
1015
1061
|
deliveryId,
|
|
1016
1062
|
sessionKey,
|
|
@@ -1018,6 +1064,10 @@ export class ClaworldRelayClient extends EventEmitter {
|
|
|
1018
1064
|
timeoutMs = DEFAULT_REPLY_ACK_TIMEOUT_MS,
|
|
1019
1065
|
httpFallback = true,
|
|
1020
1066
|
} = {}) {
|
|
1067
|
+
const ackPromise = this.waitForAcceptedAck({
|
|
1068
|
+
deliveryId,
|
|
1069
|
+
timeoutMs,
|
|
1070
|
+
});
|
|
1021
1071
|
const envelope = this.sendAccepted({
|
|
1022
1072
|
deliveryId,
|
|
1023
1073
|
sessionKey,
|
|
@@ -1025,10 +1075,7 @@ export class ClaworldRelayClient extends EventEmitter {
|
|
|
1025
1075
|
});
|
|
1026
1076
|
|
|
1027
1077
|
try {
|
|
1028
|
-
const ack = await
|
|
1029
|
-
deliveryId: envelope.deliveryId,
|
|
1030
|
-
timeoutMs,
|
|
1031
|
-
});
|
|
1078
|
+
const ack = await ackPromise;
|
|
1032
1079
|
return {
|
|
1033
1080
|
ok: true,
|
|
1034
1081
|
envelope,
|
|
@@ -1082,7 +1129,7 @@ export class ClaworldRelayClient extends EventEmitter {
|
|
|
1082
1129
|
|
|
1083
1130
|
async keepDeliverySilentHttp({ deliveryId, reason = null, source = 'openclaw-autochain' } = {}) {
|
|
1084
1131
|
const normalizedDeliveryId = normalizeOptionalText(deliveryId);
|
|
1085
|
-
const result = await this.
|
|
1132
|
+
const result = await this.requestJsonWithDeliveryVisibilityRetry(`/v1/deliveries/${encodeURIComponent(normalizedDeliveryId)}/kept-silent`, {
|
|
1086
1133
|
method: 'POST',
|
|
1087
1134
|
headers: buildRuntimeAuthHeaders(this.runtimeConfig, { 'content-type': 'application/json' }),
|
|
1088
1135
|
body: JSON.stringify({
|
|
@@ -1113,6 +1160,10 @@ export class ClaworldRelayClient extends EventEmitter {
|
|
|
1113
1160
|
timeoutMs = DEFAULT_REPLY_ACK_TIMEOUT_MS,
|
|
1114
1161
|
httpFallback = true,
|
|
1115
1162
|
} = {}) {
|
|
1163
|
+
const ackPromise = this.waitForKeepSilentAck({
|
|
1164
|
+
deliveryId,
|
|
1165
|
+
timeoutMs,
|
|
1166
|
+
});
|
|
1116
1167
|
const envelope = this.sendKeepSilent({
|
|
1117
1168
|
deliveryId,
|
|
1118
1169
|
sessionKey,
|
|
@@ -1121,10 +1172,7 @@ export class ClaworldRelayClient extends EventEmitter {
|
|
|
1121
1172
|
});
|
|
1122
1173
|
|
|
1123
1174
|
try {
|
|
1124
|
-
const ack = await
|
|
1125
|
-
deliveryId: envelope.deliveryId,
|
|
1126
|
-
timeoutMs,
|
|
1127
|
-
});
|
|
1175
|
+
const ack = await ackPromise;
|
|
1128
1176
|
return {
|
|
1129
1177
|
ok: true,
|
|
1130
1178
|
envelope,
|
|
@@ -1192,6 +1240,24 @@ export class ClaworldRelayClient extends EventEmitter {
|
|
|
1192
1240
|
}
|
|
1193
1241
|
}
|
|
1194
1242
|
|
|
1243
|
+
async submitDeliveryKeptSilent({
|
|
1244
|
+
deliveryId,
|
|
1245
|
+
sessionKey,
|
|
1246
|
+
reason = null,
|
|
1247
|
+
source = 'openclaw-autochain',
|
|
1248
|
+
timeoutMs = DEFAULT_REPLY_ACK_TIMEOUT_MS,
|
|
1249
|
+
httpFallback = true,
|
|
1250
|
+
} = {}) {
|
|
1251
|
+
return await this.sendKeepSilentAndWaitForAck({
|
|
1252
|
+
deliveryId,
|
|
1253
|
+
sessionKey,
|
|
1254
|
+
reason,
|
|
1255
|
+
source,
|
|
1256
|
+
timeoutMs,
|
|
1257
|
+
httpFallback,
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1195
1261
|
async createChatRequest({ fromAgentId, displayName, agentCode, requestContext = {} } = {}) {
|
|
1196
1262
|
const normalized = normalizeChatRequestInput({ requestContext, source: 'direct_lookup' });
|
|
1197
1263
|
const normalizedDisplayName = normalizeOptionalText(displayName);
|