@agentforge/core 0.16.47 → 0.16.49

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 CHANGED
@@ -173,7 +173,7 @@ __export(index_exports, {
173
173
  });
174
174
  module.exports = __toCommonJS(index_exports);
175
175
 
176
- // src/tools/types.ts
176
+ // src/tools/types-category.ts
177
177
  var ToolCategory = /* @__PURE__ */ ((ToolCategory2) => {
178
178
  ToolCategory2["FILE_SYSTEM"] = "file-system";
179
179
  ToolCategory2["WEB"] = "web";
@@ -1290,14 +1290,125 @@ var ToolRegistry = class {
1290
1290
  }
1291
1291
  };
1292
1292
 
1293
- // src/tools/executor.ts
1294
- var logger2 = createLogger("agentforge:tools:executor");
1293
+ // src/tools/executor-metrics.ts
1294
+ function createExecutionMetrics() {
1295
+ return {
1296
+ totalExecutions: 0,
1297
+ successfulExecutions: 0,
1298
+ failedExecutions: 0,
1299
+ totalDuration: 0,
1300
+ averageDuration: 0,
1301
+ byPriority: { low: 0, normal: 0, high: 0, critical: 0 }
1302
+ };
1303
+ }
1304
+ function recordExecutionResult(metrics, priority, duration, successful) {
1305
+ metrics.totalExecutions++;
1306
+ if (successful) {
1307
+ metrics.successfulExecutions++;
1308
+ } else {
1309
+ metrics.failedExecutions++;
1310
+ }
1311
+ metrics.totalDuration += duration;
1312
+ metrics.averageDuration = metrics.totalDuration / metrics.totalExecutions;
1313
+ metrics.byPriority[priority]++;
1314
+ }
1315
+ function resetExecutionMetrics(metrics) {
1316
+ metrics.totalExecutions = 0;
1317
+ metrics.successfulExecutions = 0;
1318
+ metrics.failedExecutions = 0;
1319
+ metrics.totalDuration = 0;
1320
+ metrics.averageDuration = 0;
1321
+ metrics.byPriority = { low: 0, normal: 0, high: 0, critical: 0 };
1322
+ }
1323
+ function snapshotExecutionMetrics(metrics) {
1324
+ return {
1325
+ ...metrics,
1326
+ byPriority: { ...metrics.byPriority }
1327
+ };
1328
+ }
1329
+
1330
+ // src/tools/executor-retry.ts
1331
+ function calculateBackoff(attempt, policy) {
1332
+ const initialDelay = policy.initialDelay || 1e3;
1333
+ const maxDelay = policy.maxDelay || 3e4;
1334
+ let delay;
1335
+ switch (policy.backoff) {
1336
+ case "linear":
1337
+ delay = initialDelay * attempt;
1338
+ break;
1339
+ case "exponential":
1340
+ delay = initialDelay * Math.pow(2, attempt - 1);
1341
+ break;
1342
+ case "fixed":
1343
+ default:
1344
+ delay = initialDelay;
1345
+ }
1346
+ return Math.min(delay, maxDelay);
1347
+ }
1348
+ function toError(error) {
1349
+ if (error instanceof Error) {
1350
+ return error;
1351
+ }
1352
+ return new Error(String(error));
1353
+ }
1354
+ function resolveExecutionMethod(tool, logger6) {
1355
+ const executeFn = tool.invoke || tool.execute;
1356
+ if (!executeFn) {
1357
+ throw new Error(
1358
+ "Tool must implement invoke() method. Tools created with createTool() or toolBuilder automatically have this method. If you are manually constructing a tool, ensure it has an invoke() method."
1359
+ );
1360
+ }
1361
+ if (!tool.invoke && tool.execute) {
1362
+ logger6.warn(
1363
+ `Tool "${tool.metadata?.name ?? tool.name ?? "unknown"}" only implements execute() which is deprecated. Please update to implement invoke() as the primary method. execute() will be removed in v1.0.0.`
1364
+ );
1365
+ }
1366
+ return executeFn;
1367
+ }
1368
+ async function executeWithRetry(tool, input, policy, logger6) {
1369
+ const executeFn = resolveExecutionMethod(tool, logger6);
1370
+ if (!policy) {
1371
+ return await executeFn.call(tool, input);
1372
+ }
1373
+ if (!Number.isInteger(policy.maxAttempts) || policy.maxAttempts < 1) {
1374
+ throw new Error(
1375
+ `Invalid retry policy: maxAttempts must be an integer >= 1 (received ${String(policy.maxAttempts)})`
1376
+ );
1377
+ }
1378
+ let lastError;
1379
+ for (let attempt = 1; attempt <= policy.maxAttempts; attempt++) {
1380
+ try {
1381
+ return await executeFn.call(tool, input);
1382
+ } catch (error) {
1383
+ const currentError = toError(error);
1384
+ lastError = currentError;
1385
+ if (policy.retryableErrors && policy.retryableErrors.length > 0) {
1386
+ const isRetryable = policy.retryableErrors.some(
1387
+ (message) => currentError.message.includes(message)
1388
+ );
1389
+ if (!isRetryable) {
1390
+ throw currentError;
1391
+ }
1392
+ }
1393
+ if (attempt < policy.maxAttempts) {
1394
+ const delay = calculateBackoff(attempt, policy);
1395
+ await new Promise((resolve) => setTimeout(resolve, delay));
1396
+ }
1397
+ }
1398
+ }
1399
+ throw lastError ?? new Error("Tool execution failed after retries");
1400
+ }
1401
+
1402
+ // src/tools/executor-types.ts
1295
1403
  var PRIORITY_ORDER = {
1296
1404
  critical: 0,
1297
1405
  high: 1,
1298
1406
  normal: 2,
1299
1407
  low: 3
1300
1408
  };
1409
+
1410
+ // src/tools/executor.ts
1411
+ var logger2 = createLogger("agentforge:core:tools:executor");
1301
1412
  function createToolExecutor(config = {}) {
1302
1413
  const {
1303
1414
  maxConcurrent = 5,
@@ -1310,119 +1421,47 @@ function createToolExecutor(config = {}) {
1310
1421
  } = config;
1311
1422
  let activeExecutions = 0;
1312
1423
  const queue = [];
1313
- const metrics = {
1314
- totalExecutions: 0,
1315
- successfulExecutions: 0,
1316
- failedExecutions: 0,
1317
- totalDuration: 0,
1318
- averageDuration: 0,
1319
- byPriority: { low: 0, normal: 0, high: 0, critical: 0 }
1320
- };
1321
- function calculateBackoff(attempt, policy) {
1322
- const initialDelay = policy.initialDelay || 1e3;
1323
- const maxDelay = policy.maxDelay || 3e4;
1324
- let delay;
1325
- switch (policy.backoff) {
1326
- case "linear":
1327
- delay = initialDelay * attempt;
1328
- break;
1329
- case "exponential":
1330
- delay = initialDelay * Math.pow(2, attempt - 1);
1331
- break;
1332
- case "fixed":
1333
- default:
1334
- delay = initialDelay;
1335
- }
1336
- return Math.min(delay, maxDelay);
1337
- }
1338
- function toError2(error) {
1339
- if (error instanceof Error) {
1340
- return error;
1341
- }
1342
- return new Error(String(error));
1343
- }
1344
- async function executeWithRetry(tool, input, policy) {
1345
- const executeFn = tool.invoke || tool.execute;
1346
- if (!executeFn) {
1347
- throw new Error(
1348
- "Tool must implement invoke() method. Tools created with createTool() or toolBuilder automatically have this method. If you are manually constructing a tool, ensure it has an invoke() method."
1349
- );
1350
- }
1351
- if (!tool.invoke && tool.execute) {
1352
- logger2.warn(
1353
- `Tool "${tool.metadata?.name || "unknown"}" only implements execute() which is deprecated. Please update to implement invoke() as the primary method. execute() will be removed in v1.0.0.`
1354
- );
1355
- }
1356
- if (!policy) {
1357
- return await executeFn.call(tool, input);
1358
- }
1359
- if (!Number.isInteger(policy.maxAttempts) || policy.maxAttempts < 1) {
1360
- throw new Error(
1361
- `Invalid retry policy: maxAttempts must be an integer >= 1 (received ${String(policy.maxAttempts)})`
1362
- );
1363
- }
1364
- let lastError;
1365
- for (let attempt = 1; attempt <= policy.maxAttempts; attempt++) {
1366
- try {
1367
- return await executeFn.call(tool, input);
1368
- } catch (error) {
1369
- const currentError = toError2(error);
1370
- lastError = currentError;
1371
- if (policy.retryableErrors && policy.retryableErrors.length > 0) {
1372
- const isRetryable = policy.retryableErrors.some(
1373
- (msg) => currentError.message.includes(msg)
1374
- );
1375
- if (!isRetryable) {
1376
- throw currentError;
1377
- }
1378
- }
1379
- if (attempt < policy.maxAttempts) {
1380
- const delay = calculateBackoff(attempt, policy);
1381
- await new Promise((resolve) => setTimeout(resolve, delay));
1382
- }
1383
- }
1384
- }
1385
- throw lastError ?? new Error("Tool execution failed after retries");
1386
- }
1424
+ const metrics = createExecutionMetrics();
1387
1425
  async function executeSingle(tool, input, priority) {
1388
1426
  const startTime = Date.now();
1427
+ let timeoutId;
1389
1428
  try {
1390
1429
  onExecutionStart?.(tool, input);
1391
1430
  const result = await Promise.race([
1392
- executeWithRetry(tool, input, retryPolicy),
1393
- new Promise(
1394
- (_, reject) => setTimeout(() => reject(new Error("Tool execution timeout")), timeout2)
1395
- )
1431
+ executeWithRetry(tool, input, retryPolicy, logger2),
1432
+ new Promise((_, reject) => {
1433
+ timeoutId = setTimeout(() => reject(new Error("Tool execution timeout")), timeout2);
1434
+ })
1396
1435
  ]);
1397
1436
  const duration = Date.now() - startTime;
1398
- metrics.totalExecutions++;
1399
- metrics.successfulExecutions++;
1400
- metrics.totalDuration += duration;
1401
- metrics.averageDuration = metrics.totalDuration / metrics.totalExecutions;
1402
- metrics.byPriority[priority]++;
1437
+ recordExecutionResult(metrics, priority, duration, true);
1403
1438
  onExecutionComplete?.(tool, input, result, duration);
1404
1439
  return result;
1405
1440
  } catch (error) {
1406
1441
  const duration = Date.now() - startTime;
1407
- const normalizedError = toError2(error);
1408
- metrics.totalExecutions++;
1409
- metrics.failedExecutions++;
1410
- metrics.totalDuration += duration;
1411
- metrics.averageDuration = metrics.totalDuration / metrics.totalExecutions;
1412
- metrics.byPriority[priority]++;
1442
+ const normalizedError = toError(error);
1443
+ recordExecutionResult(metrics, priority, duration, false);
1413
1444
  onExecutionError?.(tool, input, normalizedError, duration);
1414
1445
  throw normalizedError;
1446
+ } finally {
1447
+ if (timeoutId) {
1448
+ clearTimeout(timeoutId);
1449
+ }
1415
1450
  }
1416
1451
  }
1417
- async function processQueue() {
1452
+ function processQueue() {
1418
1453
  while (queue.length > 0 && activeExecutions < maxConcurrent) {
1419
1454
  queue.sort((a, b) => {
1420
1455
  const priorityDiff = PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority];
1421
- if (priorityDiff !== 0) return priorityDiff;
1456
+ if (priorityDiff !== 0) {
1457
+ return priorityDiff;
1458
+ }
1422
1459
  return a.timestamp - b.timestamp;
1423
1460
  });
1424
1461
  const execution = queue.shift();
1425
- if (!execution) break;
1462
+ if (!execution) {
1463
+ break;
1464
+ }
1426
1465
  activeExecutions++;
1427
1466
  executeSingle(execution.tool, execution.input, execution.priority).then((result) => {
1428
1467
  execution.resolve(result);
@@ -1451,20 +1490,15 @@ function createToolExecutor(config = {}) {
1451
1490
  async function executeParallel(executions) {
1452
1491
  return Promise.all(
1453
1492
  executions.map(
1454
- (exec) => execute(exec.tool, exec.input, { priority: exec.priority })
1493
+ (execution) => execute(execution.tool, execution.input, { priority: execution.priority })
1455
1494
  )
1456
1495
  );
1457
1496
  }
1458
1497
  function getMetrics() {
1459
- return { ...metrics };
1498
+ return snapshotExecutionMetrics(metrics);
1460
1499
  }
1461
1500
  function resetMetrics() {
1462
- metrics.totalExecutions = 0;
1463
- metrics.successfulExecutions = 0;
1464
- metrics.failedExecutions = 0;
1465
- metrics.totalDuration = 0;
1466
- metrics.averageDuration = 0;
1467
- metrics.byPriority = { low: 0, normal: 0, high: 0, critical: 0 };
1501
+ resetExecutionMetrics(metrics);
1468
1502
  }
1469
1503
  function getQueueStatus() {
1470
1504
  return {
@@ -1787,7 +1821,7 @@ function isConditionalStep(step) {
1787
1821
  function calculateRetryDelay(attempt, delay, backoff) {
1788
1822
  return backoff === "exponential" ? delay * Math.pow(2, attempt - 1) : delay * attempt;
1789
1823
  }
1790
- function toError(error) {
1824
+ function toError2(error) {
1791
1825
  return error instanceof Error ? error : new Error(String(error));
1792
1826
  }
1793
1827
  function sequential(tools) {
@@ -1860,7 +1894,7 @@ function retry(tool, options = {}) {
1860
1894
  try {
1861
1895
  return await tool.invoke(input);
1862
1896
  } catch (error) {
1863
- lastError = toError(error);
1897
+ lastError = toError2(error);
1864
1898
  if (attempt < maxAttempts) {
1865
1899
  const waitTime = calculateRetryDelay(attempt, delay, backoff);
1866
1900
  await new Promise((resolve) => setTimeout(resolve, waitTime));