@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.js CHANGED
@@ -1,4 +1,4 @@
1
- // src/tools/types.ts
1
+ // src/tools/types-category.ts
2
2
  var ToolCategory = /* @__PURE__ */ ((ToolCategory2) => {
3
3
  ToolCategory2["FILE_SYSTEM"] = "file-system";
4
4
  ToolCategory2["WEB"] = "web";
@@ -1115,14 +1115,125 @@ var ToolRegistry = class {
1115
1115
  }
1116
1116
  };
1117
1117
 
1118
- // src/tools/executor.ts
1119
- var logger2 = createLogger("agentforge:tools:executor");
1118
+ // src/tools/executor-metrics.ts
1119
+ function createExecutionMetrics() {
1120
+ return {
1121
+ totalExecutions: 0,
1122
+ successfulExecutions: 0,
1123
+ failedExecutions: 0,
1124
+ totalDuration: 0,
1125
+ averageDuration: 0,
1126
+ byPriority: { low: 0, normal: 0, high: 0, critical: 0 }
1127
+ };
1128
+ }
1129
+ function recordExecutionResult(metrics, priority, duration, successful) {
1130
+ metrics.totalExecutions++;
1131
+ if (successful) {
1132
+ metrics.successfulExecutions++;
1133
+ } else {
1134
+ metrics.failedExecutions++;
1135
+ }
1136
+ metrics.totalDuration += duration;
1137
+ metrics.averageDuration = metrics.totalDuration / metrics.totalExecutions;
1138
+ metrics.byPriority[priority]++;
1139
+ }
1140
+ function resetExecutionMetrics(metrics) {
1141
+ metrics.totalExecutions = 0;
1142
+ metrics.successfulExecutions = 0;
1143
+ metrics.failedExecutions = 0;
1144
+ metrics.totalDuration = 0;
1145
+ metrics.averageDuration = 0;
1146
+ metrics.byPriority = { low: 0, normal: 0, high: 0, critical: 0 };
1147
+ }
1148
+ function snapshotExecutionMetrics(metrics) {
1149
+ return {
1150
+ ...metrics,
1151
+ byPriority: { ...metrics.byPriority }
1152
+ };
1153
+ }
1154
+
1155
+ // src/tools/executor-retry.ts
1156
+ function calculateBackoff(attempt, policy) {
1157
+ const initialDelay = policy.initialDelay || 1e3;
1158
+ const maxDelay = policy.maxDelay || 3e4;
1159
+ let delay;
1160
+ switch (policy.backoff) {
1161
+ case "linear":
1162
+ delay = initialDelay * attempt;
1163
+ break;
1164
+ case "exponential":
1165
+ delay = initialDelay * Math.pow(2, attempt - 1);
1166
+ break;
1167
+ case "fixed":
1168
+ default:
1169
+ delay = initialDelay;
1170
+ }
1171
+ return Math.min(delay, maxDelay);
1172
+ }
1173
+ function toError(error) {
1174
+ if (error instanceof Error) {
1175
+ return error;
1176
+ }
1177
+ return new Error(String(error));
1178
+ }
1179
+ function resolveExecutionMethod(tool, logger6) {
1180
+ const executeFn = tool.invoke || tool.execute;
1181
+ if (!executeFn) {
1182
+ throw new Error(
1183
+ "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."
1184
+ );
1185
+ }
1186
+ if (!tool.invoke && tool.execute) {
1187
+ logger6.warn(
1188
+ `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.`
1189
+ );
1190
+ }
1191
+ return executeFn;
1192
+ }
1193
+ async function executeWithRetry(tool, input, policy, logger6) {
1194
+ const executeFn = resolveExecutionMethod(tool, logger6);
1195
+ if (!policy) {
1196
+ return await executeFn.call(tool, input);
1197
+ }
1198
+ if (!Number.isInteger(policy.maxAttempts) || policy.maxAttempts < 1) {
1199
+ throw new Error(
1200
+ `Invalid retry policy: maxAttempts must be an integer >= 1 (received ${String(policy.maxAttempts)})`
1201
+ );
1202
+ }
1203
+ let lastError;
1204
+ for (let attempt = 1; attempt <= policy.maxAttempts; attempt++) {
1205
+ try {
1206
+ return await executeFn.call(tool, input);
1207
+ } catch (error) {
1208
+ const currentError = toError(error);
1209
+ lastError = currentError;
1210
+ if (policy.retryableErrors && policy.retryableErrors.length > 0) {
1211
+ const isRetryable = policy.retryableErrors.some(
1212
+ (message) => currentError.message.includes(message)
1213
+ );
1214
+ if (!isRetryable) {
1215
+ throw currentError;
1216
+ }
1217
+ }
1218
+ if (attempt < policy.maxAttempts) {
1219
+ const delay = calculateBackoff(attempt, policy);
1220
+ await new Promise((resolve) => setTimeout(resolve, delay));
1221
+ }
1222
+ }
1223
+ }
1224
+ throw lastError ?? new Error("Tool execution failed after retries");
1225
+ }
1226
+
1227
+ // src/tools/executor-types.ts
1120
1228
  var PRIORITY_ORDER = {
1121
1229
  critical: 0,
1122
1230
  high: 1,
1123
1231
  normal: 2,
1124
1232
  low: 3
1125
1233
  };
1234
+
1235
+ // src/tools/executor.ts
1236
+ var logger2 = createLogger("agentforge:core:tools:executor");
1126
1237
  function createToolExecutor(config = {}) {
1127
1238
  const {
1128
1239
  maxConcurrent = 5,
@@ -1135,119 +1246,47 @@ function createToolExecutor(config = {}) {
1135
1246
  } = config;
1136
1247
  let activeExecutions = 0;
1137
1248
  const queue = [];
1138
- const metrics = {
1139
- totalExecutions: 0,
1140
- successfulExecutions: 0,
1141
- failedExecutions: 0,
1142
- totalDuration: 0,
1143
- averageDuration: 0,
1144
- byPriority: { low: 0, normal: 0, high: 0, critical: 0 }
1145
- };
1146
- function calculateBackoff(attempt, policy) {
1147
- const initialDelay = policy.initialDelay || 1e3;
1148
- const maxDelay = policy.maxDelay || 3e4;
1149
- let delay;
1150
- switch (policy.backoff) {
1151
- case "linear":
1152
- delay = initialDelay * attempt;
1153
- break;
1154
- case "exponential":
1155
- delay = initialDelay * Math.pow(2, attempt - 1);
1156
- break;
1157
- case "fixed":
1158
- default:
1159
- delay = initialDelay;
1160
- }
1161
- return Math.min(delay, maxDelay);
1162
- }
1163
- function toError2(error) {
1164
- if (error instanceof Error) {
1165
- return error;
1166
- }
1167
- return new Error(String(error));
1168
- }
1169
- async function executeWithRetry(tool, input, policy) {
1170
- const executeFn = tool.invoke || tool.execute;
1171
- if (!executeFn) {
1172
- throw new Error(
1173
- "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."
1174
- );
1175
- }
1176
- if (!tool.invoke && tool.execute) {
1177
- logger2.warn(
1178
- `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.`
1179
- );
1180
- }
1181
- if (!policy) {
1182
- return await executeFn.call(tool, input);
1183
- }
1184
- if (!Number.isInteger(policy.maxAttempts) || policy.maxAttempts < 1) {
1185
- throw new Error(
1186
- `Invalid retry policy: maxAttempts must be an integer >= 1 (received ${String(policy.maxAttempts)})`
1187
- );
1188
- }
1189
- let lastError;
1190
- for (let attempt = 1; attempt <= policy.maxAttempts; attempt++) {
1191
- try {
1192
- return await executeFn.call(tool, input);
1193
- } catch (error) {
1194
- const currentError = toError2(error);
1195
- lastError = currentError;
1196
- if (policy.retryableErrors && policy.retryableErrors.length > 0) {
1197
- const isRetryable = policy.retryableErrors.some(
1198
- (msg) => currentError.message.includes(msg)
1199
- );
1200
- if (!isRetryable) {
1201
- throw currentError;
1202
- }
1203
- }
1204
- if (attempt < policy.maxAttempts) {
1205
- const delay = calculateBackoff(attempt, policy);
1206
- await new Promise((resolve) => setTimeout(resolve, delay));
1207
- }
1208
- }
1209
- }
1210
- throw lastError ?? new Error("Tool execution failed after retries");
1211
- }
1249
+ const metrics = createExecutionMetrics();
1212
1250
  async function executeSingle(tool, input, priority) {
1213
1251
  const startTime = Date.now();
1252
+ let timeoutId;
1214
1253
  try {
1215
1254
  onExecutionStart?.(tool, input);
1216
1255
  const result = await Promise.race([
1217
- executeWithRetry(tool, input, retryPolicy),
1218
- new Promise(
1219
- (_, reject) => setTimeout(() => reject(new Error("Tool execution timeout")), timeout2)
1220
- )
1256
+ executeWithRetry(tool, input, retryPolicy, logger2),
1257
+ new Promise((_, reject) => {
1258
+ timeoutId = setTimeout(() => reject(new Error("Tool execution timeout")), timeout2);
1259
+ })
1221
1260
  ]);
1222
1261
  const duration = Date.now() - startTime;
1223
- metrics.totalExecutions++;
1224
- metrics.successfulExecutions++;
1225
- metrics.totalDuration += duration;
1226
- metrics.averageDuration = metrics.totalDuration / metrics.totalExecutions;
1227
- metrics.byPriority[priority]++;
1262
+ recordExecutionResult(metrics, priority, duration, true);
1228
1263
  onExecutionComplete?.(tool, input, result, duration);
1229
1264
  return result;
1230
1265
  } catch (error) {
1231
1266
  const duration = Date.now() - startTime;
1232
- const normalizedError = toError2(error);
1233
- metrics.totalExecutions++;
1234
- metrics.failedExecutions++;
1235
- metrics.totalDuration += duration;
1236
- metrics.averageDuration = metrics.totalDuration / metrics.totalExecutions;
1237
- metrics.byPriority[priority]++;
1267
+ const normalizedError = toError(error);
1268
+ recordExecutionResult(metrics, priority, duration, false);
1238
1269
  onExecutionError?.(tool, input, normalizedError, duration);
1239
1270
  throw normalizedError;
1271
+ } finally {
1272
+ if (timeoutId) {
1273
+ clearTimeout(timeoutId);
1274
+ }
1240
1275
  }
1241
1276
  }
1242
- async function processQueue() {
1277
+ function processQueue() {
1243
1278
  while (queue.length > 0 && activeExecutions < maxConcurrent) {
1244
1279
  queue.sort((a, b) => {
1245
1280
  const priorityDiff = PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority];
1246
- if (priorityDiff !== 0) return priorityDiff;
1281
+ if (priorityDiff !== 0) {
1282
+ return priorityDiff;
1283
+ }
1247
1284
  return a.timestamp - b.timestamp;
1248
1285
  });
1249
1286
  const execution = queue.shift();
1250
- if (!execution) break;
1287
+ if (!execution) {
1288
+ break;
1289
+ }
1251
1290
  activeExecutions++;
1252
1291
  executeSingle(execution.tool, execution.input, execution.priority).then((result) => {
1253
1292
  execution.resolve(result);
@@ -1276,20 +1315,15 @@ function createToolExecutor(config = {}) {
1276
1315
  async function executeParallel(executions) {
1277
1316
  return Promise.all(
1278
1317
  executions.map(
1279
- (exec) => execute(exec.tool, exec.input, { priority: exec.priority })
1318
+ (execution) => execute(execution.tool, execution.input, { priority: execution.priority })
1280
1319
  )
1281
1320
  );
1282
1321
  }
1283
1322
  function getMetrics() {
1284
- return { ...metrics };
1323
+ return snapshotExecutionMetrics(metrics);
1285
1324
  }
1286
1325
  function resetMetrics() {
1287
- metrics.totalExecutions = 0;
1288
- metrics.successfulExecutions = 0;
1289
- metrics.failedExecutions = 0;
1290
- metrics.totalDuration = 0;
1291
- metrics.averageDuration = 0;
1292
- metrics.byPriority = { low: 0, normal: 0, high: 0, critical: 0 };
1326
+ resetExecutionMetrics(metrics);
1293
1327
  }
1294
1328
  function getQueueStatus() {
1295
1329
  return {
@@ -1612,7 +1646,7 @@ function isConditionalStep(step) {
1612
1646
  function calculateRetryDelay(attempt, delay, backoff) {
1613
1647
  return backoff === "exponential" ? delay * Math.pow(2, attempt - 1) : delay * attempt;
1614
1648
  }
1615
- function toError(error) {
1649
+ function toError2(error) {
1616
1650
  return error instanceof Error ? error : new Error(String(error));
1617
1651
  }
1618
1652
  function sequential(tools) {
@@ -1685,7 +1719,7 @@ function retry(tool, options = {}) {
1685
1719
  try {
1686
1720
  return await tool.invoke(input);
1687
1721
  } catch (error) {
1688
- lastError = toError(error);
1722
+ lastError = toError2(error);
1689
1723
  if (attempt < maxAttempts) {
1690
1724
  const waitTime = calculateRetryDelay(attempt, delay, backoff);
1691
1725
  await new Promise((resolve) => setTimeout(resolve, waitTime));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentforge/core",
3
- "version": "0.16.47",
3
+ "version": "0.16.49",
4
4
  "description": "Production-ready TypeScript agent framework built on LangGraph with orchestration, middleware, and typed abstractions.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",