@agentforge/core 0.18.6 → 0.18.8
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/dist/index.cjs +73 -72
- package/dist/index.js +73 -72
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1245,6 +1245,47 @@ function snapshotExecutionMetrics(metrics) {
|
|
|
1245
1245
|
};
|
|
1246
1246
|
}
|
|
1247
1247
|
|
|
1248
|
+
// src/tools/execution-resilience.ts
|
|
1249
|
+
function normalizeThrownValue(error) {
|
|
1250
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
1251
|
+
}
|
|
1252
|
+
async function executeWithRetries(execute, maxAttempts, retryDelay, shouldRetry) {
|
|
1253
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1254
|
+
try {
|
|
1255
|
+
return await execute();
|
|
1256
|
+
} catch (thrownValue) {
|
|
1257
|
+
const error = normalizeThrownValue(thrownValue);
|
|
1258
|
+
if (attempt === maxAttempts || !shouldRetry(error)) {
|
|
1259
|
+
throw error;
|
|
1260
|
+
}
|
|
1261
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelay(attempt, error)));
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
throw new Error("Retry execution requires at least one attempt");
|
|
1265
|
+
}
|
|
1266
|
+
async function executeWithTimeout(execute, timeoutMs, timeoutError, startOrder = "timeout-first") {
|
|
1267
|
+
let timeoutId;
|
|
1268
|
+
const startTimeout = () => new Promise((_, reject) => {
|
|
1269
|
+
timeoutId = setTimeout(() => reject(timeoutError()), timeoutMs);
|
|
1270
|
+
});
|
|
1271
|
+
try {
|
|
1272
|
+
let executionPromise;
|
|
1273
|
+
let timeoutPromise;
|
|
1274
|
+
if (startOrder === "execution-first") {
|
|
1275
|
+
executionPromise = execute();
|
|
1276
|
+
timeoutPromise = startTimeout();
|
|
1277
|
+
} else {
|
|
1278
|
+
timeoutPromise = startTimeout();
|
|
1279
|
+
executionPromise = execute();
|
|
1280
|
+
}
|
|
1281
|
+
return await Promise.race([executionPromise, timeoutPromise]);
|
|
1282
|
+
} finally {
|
|
1283
|
+
if (timeoutId !== void 0) {
|
|
1284
|
+
clearTimeout(timeoutId);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1248
1289
|
// src/tools/executor-retry.ts
|
|
1249
1290
|
function calculateBackoff(attempt, policy) {
|
|
1250
1291
|
const initialDelay = policy.initialDelay || 1e3;
|
|
@@ -1264,10 +1305,7 @@ function calculateBackoff(attempt, policy) {
|
|
|
1264
1305
|
return Math.min(delay, maxDelay);
|
|
1265
1306
|
}
|
|
1266
1307
|
function toError(error) {
|
|
1267
|
-
|
|
1268
|
-
return error;
|
|
1269
|
-
}
|
|
1270
|
-
return new Error(String(error));
|
|
1308
|
+
return normalizeThrownValue(error);
|
|
1271
1309
|
}
|
|
1272
1310
|
function resolveExecutionMethod(tool, logger6) {
|
|
1273
1311
|
const executeFn = tool.invoke || tool.execute;
|
|
@@ -1293,28 +1331,20 @@ async function executeWithRetry(tool, input, policy, logger6) {
|
|
|
1293
1331
|
`Invalid retry policy: maxAttempts must be an integer >= 1 (received ${String(policy.maxAttempts)})`
|
|
1294
1332
|
);
|
|
1295
1333
|
}
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
}
|
|
1311
|
-
if (attempt < policy.maxAttempts) {
|
|
1312
|
-
const delay = calculateBackoff(attempt, policy);
|
|
1313
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
}
|
|
1317
|
-
throw lastError ?? new Error("Tool execution failed after retries");
|
|
1334
|
+
return executeWithRetries(
|
|
1335
|
+
() => executeFn.call(tool, input),
|
|
1336
|
+
policy.maxAttempts,
|
|
1337
|
+
(attempt) => calculateBackoff(attempt, policy),
|
|
1338
|
+
(error) => !policy.retryableErrors?.length || policy.retryableErrors.some((message) => error.message.includes(message))
|
|
1339
|
+
);
|
|
1340
|
+
}
|
|
1341
|
+
async function executeWithTimeout2(execute, timeout2) {
|
|
1342
|
+
return executeWithTimeout(
|
|
1343
|
+
execute,
|
|
1344
|
+
timeout2,
|
|
1345
|
+
() => new Error("Tool execution timeout"),
|
|
1346
|
+
"execution-first"
|
|
1347
|
+
);
|
|
1318
1348
|
}
|
|
1319
1349
|
|
|
1320
1350
|
// src/tools/executor-types.ts
|
|
@@ -1342,15 +1372,12 @@ function createToolExecutor(config = {}) {
|
|
|
1342
1372
|
const metrics = createExecutionMetrics();
|
|
1343
1373
|
async function executeSingle(tool, input, priority) {
|
|
1344
1374
|
const startTime = Date.now();
|
|
1345
|
-
let timeoutId;
|
|
1346
1375
|
try {
|
|
1347
1376
|
onExecutionStart?.(tool, input);
|
|
1348
|
-
const result = await
|
|
1349
|
-
executeWithRetry(tool, input, retryPolicy, logger2),
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
})
|
|
1353
|
-
]);
|
|
1377
|
+
const result = await executeWithTimeout2(
|
|
1378
|
+
() => executeWithRetry(tool, input, retryPolicy, logger2),
|
|
1379
|
+
timeout2
|
|
1380
|
+
);
|
|
1354
1381
|
const duration = Date.now() - startTime;
|
|
1355
1382
|
recordExecutionResult(metrics, priority, duration, true);
|
|
1356
1383
|
onExecutionComplete?.(tool, input, result, duration);
|
|
@@ -1361,10 +1388,6 @@ function createToolExecutor(config = {}) {
|
|
|
1361
1388
|
recordExecutionResult(metrics, priority, duration, false);
|
|
1362
1389
|
onExecutionError?.(tool, input, normalizedError, duration);
|
|
1363
1390
|
throw normalizedError;
|
|
1364
|
-
} finally {
|
|
1365
|
-
if (timeoutId) {
|
|
1366
|
-
clearTimeout(timeoutId);
|
|
1367
|
-
}
|
|
1368
1391
|
}
|
|
1369
1392
|
}
|
|
1370
1393
|
function processQueue() {
|
|
@@ -1739,9 +1762,6 @@ function isConditionalStep(step) {
|
|
|
1739
1762
|
function calculateRetryDelay(attempt, delay, backoff) {
|
|
1740
1763
|
return backoff === "exponential" ? delay * Math.pow(2, attempt - 1) : delay * attempt;
|
|
1741
1764
|
}
|
|
1742
|
-
function toError2(error) {
|
|
1743
|
-
return error instanceof Error ? error : new Error(String(error));
|
|
1744
|
-
}
|
|
1745
1765
|
function sequential(tools) {
|
|
1746
1766
|
return {
|
|
1747
1767
|
name: `sequential(${tools.map((t) => t.name).join(" -> ")})`,
|
|
@@ -1806,42 +1826,23 @@ function retry(tool, options = {}) {
|
|
|
1806
1826
|
return {
|
|
1807
1827
|
name: `retry(${tool.name})`,
|
|
1808
1828
|
description: `${tool.description} (with retry)`,
|
|
1809
|
-
invoke: async (input) =>
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
lastError = toError2(error);
|
|
1816
|
-
if (attempt < maxAttempts) {
|
|
1817
|
-
const waitTime = calculateRetryDelay(attempt, delay, backoff);
|
|
1818
|
-
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
1819
|
-
}
|
|
1820
|
-
}
|
|
1821
|
-
}
|
|
1822
|
-
throw lastError;
|
|
1823
|
-
}
|
|
1829
|
+
invoke: async (input) => executeWithRetries(
|
|
1830
|
+
() => tool.invoke(input),
|
|
1831
|
+
maxAttempts,
|
|
1832
|
+
(attempt) => calculateRetryDelay(attempt, delay, backoff),
|
|
1833
|
+
() => true
|
|
1834
|
+
)
|
|
1824
1835
|
};
|
|
1825
1836
|
}
|
|
1826
1837
|
function timeout(tool, ms) {
|
|
1827
1838
|
return {
|
|
1828
1839
|
name: `timeout(${tool.name})`,
|
|
1829
1840
|
description: `${tool.description} (with ${ms}ms timeout)`,
|
|
1830
|
-
invoke: async (input) =>
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
}, ms);
|
|
1836
|
-
});
|
|
1837
|
-
try {
|
|
1838
|
-
return await Promise.race([tool.invoke(input), timeoutPromise]);
|
|
1839
|
-
} finally {
|
|
1840
|
-
if (timer !== void 0) {
|
|
1841
|
-
clearTimeout(timer);
|
|
1842
|
-
}
|
|
1843
|
-
}
|
|
1844
|
-
}
|
|
1841
|
+
invoke: async (input) => executeWithTimeout(
|
|
1842
|
+
() => tool.invoke(input),
|
|
1843
|
+
ms,
|
|
1844
|
+
() => new Error(`Tool ${tool.name} timed out after ${ms}ms`)
|
|
1845
|
+
)
|
|
1845
1846
|
};
|
|
1846
1847
|
}
|
|
1847
1848
|
function cache(tool, ttl) {
|
|
@@ -4448,7 +4449,7 @@ function toErrorPayload(error) {
|
|
|
4448
4449
|
}
|
|
4449
4450
|
return { error: String(error) };
|
|
4450
4451
|
}
|
|
4451
|
-
function
|
|
4452
|
+
function toError2(error) {
|
|
4452
4453
|
if (error instanceof Error) {
|
|
4453
4454
|
return error;
|
|
4454
4455
|
}
|
|
@@ -4483,7 +4484,7 @@ var ConnectionPool = class {
|
|
|
4483
4484
|
const interval = healthCheck.interval || 3e4;
|
|
4484
4485
|
this.runtime.healthCheckTimer = setInterval(() => {
|
|
4485
4486
|
performHealthChecks(this.runtime).catch((error) => {
|
|
4486
|
-
const normalizedError =
|
|
4487
|
+
const normalizedError = toError2(error);
|
|
4487
4488
|
logger4.error("Health check failed", toErrorPayload(normalizedError));
|
|
4488
4489
|
options.onHealthCheckFail?.(normalizedError);
|
|
4489
4490
|
});
|
package/dist/index.js
CHANGED
|
@@ -1069,6 +1069,47 @@ function snapshotExecutionMetrics(metrics) {
|
|
|
1069
1069
|
};
|
|
1070
1070
|
}
|
|
1071
1071
|
|
|
1072
|
+
// src/tools/execution-resilience.ts
|
|
1073
|
+
function normalizeThrownValue(error) {
|
|
1074
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
1075
|
+
}
|
|
1076
|
+
async function executeWithRetries(execute, maxAttempts, retryDelay, shouldRetry) {
|
|
1077
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1078
|
+
try {
|
|
1079
|
+
return await execute();
|
|
1080
|
+
} catch (thrownValue) {
|
|
1081
|
+
const error = normalizeThrownValue(thrownValue);
|
|
1082
|
+
if (attempt === maxAttempts || !shouldRetry(error)) {
|
|
1083
|
+
throw error;
|
|
1084
|
+
}
|
|
1085
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelay(attempt, error)));
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
throw new Error("Retry execution requires at least one attempt");
|
|
1089
|
+
}
|
|
1090
|
+
async function executeWithTimeout(execute, timeoutMs, timeoutError, startOrder = "timeout-first") {
|
|
1091
|
+
let timeoutId;
|
|
1092
|
+
const startTimeout = () => new Promise((_, reject) => {
|
|
1093
|
+
timeoutId = setTimeout(() => reject(timeoutError()), timeoutMs);
|
|
1094
|
+
});
|
|
1095
|
+
try {
|
|
1096
|
+
let executionPromise;
|
|
1097
|
+
let timeoutPromise;
|
|
1098
|
+
if (startOrder === "execution-first") {
|
|
1099
|
+
executionPromise = execute();
|
|
1100
|
+
timeoutPromise = startTimeout();
|
|
1101
|
+
} else {
|
|
1102
|
+
timeoutPromise = startTimeout();
|
|
1103
|
+
executionPromise = execute();
|
|
1104
|
+
}
|
|
1105
|
+
return await Promise.race([executionPromise, timeoutPromise]);
|
|
1106
|
+
} finally {
|
|
1107
|
+
if (timeoutId !== void 0) {
|
|
1108
|
+
clearTimeout(timeoutId);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1072
1113
|
// src/tools/executor-retry.ts
|
|
1073
1114
|
function calculateBackoff(attempt, policy) {
|
|
1074
1115
|
const initialDelay = policy.initialDelay || 1e3;
|
|
@@ -1088,10 +1129,7 @@ function calculateBackoff(attempt, policy) {
|
|
|
1088
1129
|
return Math.min(delay, maxDelay);
|
|
1089
1130
|
}
|
|
1090
1131
|
function toError(error) {
|
|
1091
|
-
|
|
1092
|
-
return error;
|
|
1093
|
-
}
|
|
1094
|
-
return new Error(String(error));
|
|
1132
|
+
return normalizeThrownValue(error);
|
|
1095
1133
|
}
|
|
1096
1134
|
function resolveExecutionMethod(tool, logger6) {
|
|
1097
1135
|
const executeFn = tool.invoke || tool.execute;
|
|
@@ -1117,28 +1155,20 @@ async function executeWithRetry(tool, input, policy, logger6) {
|
|
|
1117
1155
|
`Invalid retry policy: maxAttempts must be an integer >= 1 (received ${String(policy.maxAttempts)})`
|
|
1118
1156
|
);
|
|
1119
1157
|
}
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
}
|
|
1135
|
-
if (attempt < policy.maxAttempts) {
|
|
1136
|
-
const delay = calculateBackoff(attempt, policy);
|
|
1137
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
throw lastError ?? new Error("Tool execution failed after retries");
|
|
1158
|
+
return executeWithRetries(
|
|
1159
|
+
() => executeFn.call(tool, input),
|
|
1160
|
+
policy.maxAttempts,
|
|
1161
|
+
(attempt) => calculateBackoff(attempt, policy),
|
|
1162
|
+
(error) => !policy.retryableErrors?.length || policy.retryableErrors.some((message) => error.message.includes(message))
|
|
1163
|
+
);
|
|
1164
|
+
}
|
|
1165
|
+
async function executeWithTimeout2(execute, timeout2) {
|
|
1166
|
+
return executeWithTimeout(
|
|
1167
|
+
execute,
|
|
1168
|
+
timeout2,
|
|
1169
|
+
() => new Error("Tool execution timeout"),
|
|
1170
|
+
"execution-first"
|
|
1171
|
+
);
|
|
1142
1172
|
}
|
|
1143
1173
|
|
|
1144
1174
|
// src/tools/executor-types.ts
|
|
@@ -1166,15 +1196,12 @@ function createToolExecutor(config = {}) {
|
|
|
1166
1196
|
const metrics = createExecutionMetrics();
|
|
1167
1197
|
async function executeSingle(tool, input, priority) {
|
|
1168
1198
|
const startTime = Date.now();
|
|
1169
|
-
let timeoutId;
|
|
1170
1199
|
try {
|
|
1171
1200
|
onExecutionStart?.(tool, input);
|
|
1172
|
-
const result = await
|
|
1173
|
-
executeWithRetry(tool, input, retryPolicy, logger2),
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
})
|
|
1177
|
-
]);
|
|
1201
|
+
const result = await executeWithTimeout2(
|
|
1202
|
+
() => executeWithRetry(tool, input, retryPolicy, logger2),
|
|
1203
|
+
timeout2
|
|
1204
|
+
);
|
|
1178
1205
|
const duration = Date.now() - startTime;
|
|
1179
1206
|
recordExecutionResult(metrics, priority, duration, true);
|
|
1180
1207
|
onExecutionComplete?.(tool, input, result, duration);
|
|
@@ -1185,10 +1212,6 @@ function createToolExecutor(config = {}) {
|
|
|
1185
1212
|
recordExecutionResult(metrics, priority, duration, false);
|
|
1186
1213
|
onExecutionError?.(tool, input, normalizedError, duration);
|
|
1187
1214
|
throw normalizedError;
|
|
1188
|
-
} finally {
|
|
1189
|
-
if (timeoutId) {
|
|
1190
|
-
clearTimeout(timeoutId);
|
|
1191
|
-
}
|
|
1192
1215
|
}
|
|
1193
1216
|
}
|
|
1194
1217
|
function processQueue() {
|
|
@@ -1563,9 +1586,6 @@ function isConditionalStep(step) {
|
|
|
1563
1586
|
function calculateRetryDelay(attempt, delay, backoff) {
|
|
1564
1587
|
return backoff === "exponential" ? delay * Math.pow(2, attempt - 1) : delay * attempt;
|
|
1565
1588
|
}
|
|
1566
|
-
function toError2(error) {
|
|
1567
|
-
return error instanceof Error ? error : new Error(String(error));
|
|
1568
|
-
}
|
|
1569
1589
|
function sequential(tools) {
|
|
1570
1590
|
return {
|
|
1571
1591
|
name: `sequential(${tools.map((t) => t.name).join(" -> ")})`,
|
|
@@ -1630,42 +1650,23 @@ function retry(tool, options = {}) {
|
|
|
1630
1650
|
return {
|
|
1631
1651
|
name: `retry(${tool.name})`,
|
|
1632
1652
|
description: `${tool.description} (with retry)`,
|
|
1633
|
-
invoke: async (input) =>
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
lastError = toError2(error);
|
|
1640
|
-
if (attempt < maxAttempts) {
|
|
1641
|
-
const waitTime = calculateRetryDelay(attempt, delay, backoff);
|
|
1642
|
-
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
1643
|
-
}
|
|
1644
|
-
}
|
|
1645
|
-
}
|
|
1646
|
-
throw lastError;
|
|
1647
|
-
}
|
|
1653
|
+
invoke: async (input) => executeWithRetries(
|
|
1654
|
+
() => tool.invoke(input),
|
|
1655
|
+
maxAttempts,
|
|
1656
|
+
(attempt) => calculateRetryDelay(attempt, delay, backoff),
|
|
1657
|
+
() => true
|
|
1658
|
+
)
|
|
1648
1659
|
};
|
|
1649
1660
|
}
|
|
1650
1661
|
function timeout(tool, ms) {
|
|
1651
1662
|
return {
|
|
1652
1663
|
name: `timeout(${tool.name})`,
|
|
1653
1664
|
description: `${tool.description} (with ${ms}ms timeout)`,
|
|
1654
|
-
invoke: async (input) =>
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
}, ms);
|
|
1660
|
-
});
|
|
1661
|
-
try {
|
|
1662
|
-
return await Promise.race([tool.invoke(input), timeoutPromise]);
|
|
1663
|
-
} finally {
|
|
1664
|
-
if (timer !== void 0) {
|
|
1665
|
-
clearTimeout(timer);
|
|
1666
|
-
}
|
|
1667
|
-
}
|
|
1668
|
-
}
|
|
1665
|
+
invoke: async (input) => executeWithTimeout(
|
|
1666
|
+
() => tool.invoke(input),
|
|
1667
|
+
ms,
|
|
1668
|
+
() => new Error(`Tool ${tool.name} timed out after ${ms}ms`)
|
|
1669
|
+
)
|
|
1669
1670
|
};
|
|
1670
1671
|
}
|
|
1671
1672
|
function cache(tool, ttl) {
|
|
@@ -4272,7 +4273,7 @@ function toErrorPayload(error) {
|
|
|
4272
4273
|
}
|
|
4273
4274
|
return { error: String(error) };
|
|
4274
4275
|
}
|
|
4275
|
-
function
|
|
4276
|
+
function toError2(error) {
|
|
4276
4277
|
if (error instanceof Error) {
|
|
4277
4278
|
return error;
|
|
4278
4279
|
}
|
|
@@ -4307,7 +4308,7 @@ var ConnectionPool = class {
|
|
|
4307
4308
|
const interval = healthCheck.interval || 3e4;
|
|
4308
4309
|
this.runtime.healthCheckTimer = setInterval(() => {
|
|
4309
4310
|
performHealthChecks(this.runtime).catch((error) => {
|
|
4310
|
-
const normalizedError =
|
|
4311
|
+
const normalizedError = toError2(error);
|
|
4311
4312
|
logger4.error("Health check failed", toErrorPayload(normalizedError));
|
|
4312
4313
|
options.onHealthCheckFail?.(normalizedError);
|
|
4313
4314
|
});
|
package/package.json
CHANGED