@agentforge/core 0.15.3 → 0.15.5

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
@@ -861,6 +861,9 @@ Examples:`);
861
861
  return parts.join("\n");
862
862
  }
863
863
 
864
+ // src/tools/registry.ts
865
+ var import_zod3 = require("zod");
866
+
864
867
  // src/langgraph/observability/logger.ts
865
868
  var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
866
869
  LogLevel2["DEBUG"] = "debug";
@@ -965,6 +968,9 @@ var RegistryEvent = /* @__PURE__ */ ((RegistryEvent2) => {
965
968
  RegistryEvent2["REGISTRY_CLEARED"] = "registry:cleared";
966
969
  return RegistryEvent2;
967
970
  })(RegistryEvent || {});
971
+ function eraseToolType(tool) {
972
+ return tool;
973
+ }
968
974
  var ToolRegistry = class {
969
975
  tools = /* @__PURE__ */ new Map();
970
976
  eventHandlers = /* @__PURE__ */ new Map();
@@ -980,13 +986,14 @@ var ToolRegistry = class {
980
986
  * ```
981
987
  */
982
988
  register(tool) {
989
+ const erasedTool = eraseToolType(tool);
983
990
  const name = tool.metadata.name;
984
991
  if (this.tools.has(name)) {
985
992
  throw new Error(
986
993
  `Tool with name "${name}" is already registered. Use update() to modify it.`
987
994
  );
988
995
  }
989
- this.tools.set(name, tool);
996
+ this.tools.set(name, erasedTool);
990
997
  this.emit("tool:registered" /* TOOL_REGISTERED */, tool);
991
998
  }
992
999
  /**
@@ -1057,6 +1064,7 @@ var ToolRegistry = class {
1057
1064
  * ```
1058
1065
  */
1059
1066
  update(name, tool) {
1067
+ const erasedTool = eraseToolType(tool);
1060
1068
  if (!this.tools.has(name)) {
1061
1069
  return false;
1062
1070
  }
@@ -1065,7 +1073,7 @@ var ToolRegistry = class {
1065
1073
  `Cannot update tool: metadata.name "${tool.metadata.name}" does not match registry key "${name}". To rename a tool, remove it and register it again with the new name.`
1066
1074
  );
1067
1075
  }
1068
- this.tools.set(name, tool);
1076
+ this.tools.set(name, erasedTool);
1069
1077
  this.emit("tool:updated" /* TOOL_UPDATED */, { name, tool });
1070
1078
  return true;
1071
1079
  }
@@ -1139,7 +1147,7 @@ var ToolRegistry = class {
1139
1147
  /**
1140
1148
  * Register multiple tools at once
1141
1149
  *
1142
- * @param tools - Array of tools to register
1150
+ * @param tools - Iterable of tools to register
1143
1151
  * @throws Error if any tool name conflicts with existing tools
1144
1152
  *
1145
1153
  * @example
@@ -1148,9 +1156,10 @@ var ToolRegistry = class {
1148
1156
  * ```
1149
1157
  */
1150
1158
  registerMany(tools) {
1159
+ const toolsToRegister = Array.from(tools);
1151
1160
  const inputNames = /* @__PURE__ */ new Set();
1152
1161
  const duplicatesInInput = [];
1153
- for (const tool of tools) {
1162
+ for (const tool of toolsToRegister) {
1154
1163
  const name = tool.metadata.name;
1155
1164
  if (inputNames.has(name)) {
1156
1165
  duplicatesInInput.push(name);
@@ -1164,7 +1173,7 @@ var ToolRegistry = class {
1164
1173
  );
1165
1174
  }
1166
1175
  const conflicts = [];
1167
- for (const tool of tools) {
1176
+ for (const tool of toolsToRegister) {
1168
1177
  if (this.tools.has(tool.metadata.name)) {
1169
1178
  conflicts.push(tool.metadata.name);
1170
1179
  }
@@ -1174,7 +1183,7 @@ var ToolRegistry = class {
1174
1183
  `Cannot register tools: the following names already exist: ${conflicts.join(", ")}`
1175
1184
  );
1176
1185
  }
1177
- for (const tool of tools) {
1186
+ for (const tool of toolsToRegister) {
1178
1187
  this.register(tool);
1179
1188
  }
1180
1189
  }
@@ -1437,13 +1446,14 @@ var ToolRegistry = class {
1437
1446
  return lines;
1438
1447
  }
1439
1448
  lines.push(`- ${metadata.name}: ${metadata.description}`);
1440
- const schemaShape = tool.schema._def?.shape?.();
1449
+ const schemaShape = this.getSchemaShape(tool.schema);
1441
1450
  if (schemaShape) {
1442
1451
  const params = Object.keys(schemaShape);
1443
1452
  if (params.length > 0) {
1444
1453
  const paramDescriptions = params.map((param) => {
1445
1454
  const field = schemaShape[param];
1446
- const type = field._def?.typeName?.replace("Zod", "").toLowerCase() || "any";
1455
+ const typeName = field._def.typeName;
1456
+ const type = typeName.replace("Zod", "").toLowerCase();
1447
1457
  return `${param} (${type})`;
1448
1458
  });
1449
1459
  lines.push(` Parameters: ${paramDescriptions.join(", ")}`);
@@ -1503,6 +1513,12 @@ var ToolRegistry = class {
1503
1513
  }
1504
1514
  return lines;
1505
1515
  }
1516
+ getSchemaShape(schema) {
1517
+ if (schema instanceof import_zod3.z.ZodObject) {
1518
+ return schema.shape;
1519
+ }
1520
+ return void 0;
1521
+ }
1506
1522
  };
1507
1523
 
1508
1524
  // src/tools/executor.ts
@@ -1550,6 +1566,12 @@ function createToolExecutor(config = {}) {
1550
1566
  }
1551
1567
  return Math.min(delay, maxDelay);
1552
1568
  }
1569
+ function toError(error) {
1570
+ if (error instanceof Error) {
1571
+ return error;
1572
+ }
1573
+ return new Error(String(error));
1574
+ }
1553
1575
  async function executeWithRetry(tool, input, policy) {
1554
1576
  const executeFn = tool.invoke || tool.execute;
1555
1577
  if (!executeFn) {
@@ -1565,18 +1587,24 @@ function createToolExecutor(config = {}) {
1565
1587
  if (!policy) {
1566
1588
  return await executeFn.call(tool, input);
1567
1589
  }
1590
+ if (!Number.isInteger(policy.maxAttempts) || policy.maxAttempts < 1) {
1591
+ throw new Error(
1592
+ `Invalid retry policy: maxAttempts must be an integer >= 1 (received ${String(policy.maxAttempts)})`
1593
+ );
1594
+ }
1568
1595
  let lastError;
1569
1596
  for (let attempt = 1; attempt <= policy.maxAttempts; attempt++) {
1570
1597
  try {
1571
1598
  return await executeFn.call(tool, input);
1572
1599
  } catch (error) {
1573
- lastError = error;
1600
+ const currentError = toError(error);
1601
+ lastError = currentError;
1574
1602
  if (policy.retryableErrors && policy.retryableErrors.length > 0) {
1575
1603
  const isRetryable = policy.retryableErrors.some(
1576
- (msg) => lastError.message.includes(msg)
1604
+ (msg) => currentError.message.includes(msg)
1577
1605
  );
1578
1606
  if (!isRetryable) {
1579
- throw lastError;
1607
+ throw currentError;
1580
1608
  }
1581
1609
  }
1582
1610
  if (attempt < policy.maxAttempts) {
@@ -1585,7 +1613,7 @@ function createToolExecutor(config = {}) {
1585
1613
  }
1586
1614
  }
1587
1615
  }
1588
- throw lastError;
1616
+ throw lastError ?? new Error("Tool execution failed after retries");
1589
1617
  }
1590
1618
  async function executeSingle(tool, input, priority) {
1591
1619
  const startTime = Date.now();
@@ -1607,13 +1635,14 @@ function createToolExecutor(config = {}) {
1607
1635
  return result;
1608
1636
  } catch (error) {
1609
1637
  const duration = Date.now() - startTime;
1638
+ const normalizedError = toError(error);
1610
1639
  metrics.totalExecutions++;
1611
1640
  metrics.failedExecutions++;
1612
1641
  metrics.totalDuration += duration;
1613
1642
  metrics.averageDuration = metrics.totalDuration / metrics.totalExecutions;
1614
1643
  metrics.byPriority[priority]++;
1615
- onExecutionError?.(tool, input, error, duration);
1616
- throw error;
1644
+ onExecutionError?.(tool, input, normalizedError, duration);
1645
+ throw normalizedError;
1617
1646
  }
1618
1647
  }
1619
1648
  async function processQueue() {
@@ -2075,8 +2104,8 @@ function createToolSimulator(config) {
2075
2104
  if (!latency) return 0;
2076
2105
  const u1 = Math.random();
2077
2106
  const u2 = Math.random();
2078
- const z3 = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
2079
- return Math.max(0, latency.mean + z3 * latency.stddev);
2107
+ const z4 = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
2108
+ return Math.max(0, latency.mean + z4 * latency.stddev);
2080
2109
  }
2081
2110
  return {
2082
2111
  execute: async (toolName, input) => {
@@ -4504,8 +4533,8 @@ function createDatabasePool(options) {
4504
4533
 
4505
4534
  // src/resources/http-pool.ts
4506
4535
  var MockHttpClient = class {
4507
- constructor(config) {
4508
- this.config = config;
4536
+ constructor(_config) {
4537
+ this._config = _config;
4509
4538
  }
4510
4539
  closed = false;
4511
4540
  async get(url, config) {
@@ -4520,7 +4549,7 @@ var MockHttpClient = class {
4520
4549
  async delete(url, config) {
4521
4550
  return this.request({ ...config, url, method: "DELETE" });
4522
4551
  }
4523
- async request(config) {
4552
+ async request(_config) {
4524
4553
  if (this.closed) {
4525
4554
  throw new Error("Client is closed");
4526
4555
  }
package/dist/index.d.cts CHANGED
@@ -1173,7 +1173,9 @@ declare enum RegistryEvent {
1173
1173
  /**
1174
1174
  * Event handler type
1175
1175
  */
1176
- type EventHandler = (data: any) => void;
1176
+ type EventHandler = (data: unknown) => void;
1177
+ type RegistryTool = Tool<unknown, unknown>;
1178
+ type RegisterManyTool = Tool<never, unknown>;
1177
1179
  /**
1178
1180
  * Options for generating tool prompts
1179
1181
  */
@@ -1250,7 +1252,7 @@ declare class ToolRegistry {
1250
1252
  * registry.register(readFileTool);
1251
1253
  * ```
1252
1254
  */
1253
- register(tool: Tool<any, any>): void;
1255
+ register<TInput, TOutput>(tool: Tool<TInput, TOutput>): void;
1254
1256
  /**
1255
1257
  * Get a tool by name
1256
1258
  *
@@ -1265,7 +1267,7 @@ declare class ToolRegistry {
1265
1267
  * }
1266
1268
  * ```
1267
1269
  */
1268
- get(name: string): Tool<any, any> | undefined;
1270
+ get(name: string): RegistryTool | undefined;
1269
1271
  /**
1270
1272
  * Check if a tool exists in the registry
1271
1273
  *
@@ -1306,7 +1308,7 @@ declare class ToolRegistry {
1306
1308
  * const updated = registry.update('read-file', newReadFileTool);
1307
1309
  * ```
1308
1310
  */
1309
- update(name: string, tool: Tool<any, any>): boolean;
1311
+ update<TInput, TOutput>(name: string, tool: Tool<TInput, TOutput>): boolean;
1310
1312
  /**
1311
1313
  * Get all registered tools
1312
1314
  *
@@ -1318,7 +1320,7 @@ declare class ToolRegistry {
1318
1320
  * console.log(`Total tools: ${allTools.length}`);
1319
1321
  * ```
1320
1322
  */
1321
- getAll(): Tool<any, any>[];
1323
+ getAll(): RegistryTool[];
1322
1324
  /**
1323
1325
  * Get tools by category
1324
1326
  *
@@ -1330,7 +1332,7 @@ declare class ToolRegistry {
1330
1332
  * const fileTools = registry.getByCategory(ToolCategory.FILE_SYSTEM);
1331
1333
  * ```
1332
1334
  */
1333
- getByCategory(category: ToolCategory): Tool<any, any>[];
1335
+ getByCategory(category: ToolCategory): RegistryTool[];
1334
1336
  /**
1335
1337
  * Get tools by tag
1336
1338
  *
@@ -1342,7 +1344,7 @@ declare class ToolRegistry {
1342
1344
  * const fileTools = registry.getByTag('file');
1343
1345
  * ```
1344
1346
  */
1345
- getByTag(tag: string): Tool<any, any>[];
1347
+ getByTag(tag: string): RegistryTool[];
1346
1348
  /**
1347
1349
  * Search tools by name or description
1348
1350
  *
@@ -1357,11 +1359,11 @@ declare class ToolRegistry {
1357
1359
  * // Returns tools with 'file' in name or description
1358
1360
  * ```
1359
1361
  */
1360
- search(query: string): Tool<any, any>[];
1362
+ search(query: string): RegistryTool[];
1361
1363
  /**
1362
1364
  * Register multiple tools at once
1363
1365
  *
1364
- * @param tools - Array of tools to register
1366
+ * @param tools - Iterable of tools to register
1365
1367
  * @throws Error if any tool name conflicts with existing tools
1366
1368
  *
1367
1369
  * @example
@@ -1369,7 +1371,7 @@ declare class ToolRegistry {
1369
1371
  * registry.registerMany([tool1, tool2, tool3]);
1370
1372
  * ```
1371
1373
  */
1372
- registerMany(tools: Tool<any, any>[]): void;
1374
+ registerMany(tools: Iterable<RegisterManyTool>): void;
1373
1375
  /**
1374
1376
  * Clear all tools from the registry
1375
1377
  *
@@ -1506,6 +1508,7 @@ declare class ToolRegistry {
1506
1508
  * @private
1507
1509
  */
1508
1510
  private formatRelations;
1511
+ private getSchemaShape;
1509
1512
  }
1510
1513
 
1511
1514
  /**
@@ -1525,14 +1528,14 @@ interface ToolExecutorConfig {
1525
1528
  maxConcurrent?: number;
1526
1529
  timeout?: number;
1527
1530
  retryPolicy?: RetryPolicy;
1528
- priorityFn?: (tool: any) => Priority$1;
1529
- onExecutionStart?: (tool: any, input: any) => void;
1530
- onExecutionComplete?: (tool: any, input: any, result: any, duration: number) => void;
1531
- onExecutionError?: (tool: any, input: any, error: Error, duration: number) => void;
1531
+ priorityFn?: (tool: ExecutableTool) => Priority$1;
1532
+ onExecutionStart?: (tool: ExecutableTool, input: unknown) => void;
1533
+ onExecutionComplete?: (tool: ExecutableTool, input: unknown, result: unknown, duration: number) => void;
1534
+ onExecutionError?: (tool: ExecutableTool, input: unknown, error: Error, duration: number) => void;
1532
1535
  }
1533
1536
  interface ToolExecution {
1534
- tool: any;
1535
- input: any;
1537
+ tool: ExecutableTool;
1538
+ input: unknown;
1536
1539
  priority?: Priority$1;
1537
1540
  }
1538
1541
  interface ExecutionMetrics {
@@ -1543,14 +1546,21 @@ interface ExecutionMetrics {
1543
1546
  averageDuration: number;
1544
1547
  byPriority: Record<Priority$1, number>;
1545
1548
  }
1549
+ interface ExecutableTool<TInput = unknown, TOutput = unknown> {
1550
+ metadata?: {
1551
+ name?: string;
1552
+ };
1553
+ invoke?: (input: TInput) => Promise<TOutput>;
1554
+ execute?: (input: TInput) => Promise<TOutput>;
1555
+ }
1546
1556
  /**
1547
1557
  * Create a tool executor with resource management
1548
1558
  */
1549
1559
  declare function createToolExecutor(config?: ToolExecutorConfig): {
1550
- execute: (tool: any, input: any, options?: {
1560
+ execute: (tool: ExecutableTool, input: unknown, options?: {
1551
1561
  priority?: Priority$1;
1552
- }) => Promise<any>;
1553
- executeParallel: (executions: ToolExecution[]) => Promise<any[]>;
1562
+ }) => Promise<unknown>;
1563
+ executeParallel: (executions: ToolExecution[]) => Promise<unknown[]>;
1554
1564
  getMetrics: () => ExecutionMetrics;
1555
1565
  resetMetrics: () => void;
1556
1566
  getQueueStatus: () => {
@@ -4986,22 +4996,22 @@ interface HttpPoolConfig extends PoolConfig {
4986
4996
  keepAliveMsecs?: number;
4987
4997
  }
4988
4998
  interface HttpClient {
4989
- get<T = any>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>;
4990
- post<T = any>(url: string, data?: any, config?: RequestConfig): Promise<HttpResponse<T>>;
4991
- put<T = any>(url: string, data?: any, config?: RequestConfig): Promise<HttpResponse<T>>;
4992
- delete<T = any>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>;
4993
- request<T = any>(config: RequestConfig): Promise<HttpResponse<T>>;
4999
+ get<T = unknown>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>;
5000
+ post<T = unknown, TData = unknown>(url: string, data?: TData, config?: RequestConfig<TData>): Promise<HttpResponse<T>>;
5001
+ put<T = unknown, TData = unknown>(url: string, data?: TData, config?: RequestConfig<TData>): Promise<HttpResponse<T>>;
5002
+ delete<T = unknown>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>;
5003
+ request<T = unknown, TData = unknown>(config: RequestConfig<TData>): Promise<HttpResponse<T>>;
4994
5004
  close(): Promise<void>;
4995
5005
  }
4996
- interface RequestConfig {
5006
+ interface RequestConfig<TData = unknown> {
4997
5007
  url?: string;
4998
5008
  method?: string;
4999
5009
  headers?: Record<string, string>;
5000
- params?: Record<string, any>;
5001
- data?: any;
5010
+ params?: Record<string, unknown>;
5011
+ data?: TData;
5002
5012
  timeout?: number;
5003
5013
  }
5004
- interface HttpResponse<T = any> {
5014
+ interface HttpResponse<T = unknown> {
5005
5015
  data: T;
5006
5016
  status: number;
5007
5017
  statusText: string;
@@ -5023,7 +5033,7 @@ declare class HttpPool {
5023
5033
  constructor(options: HttpPoolOptions);
5024
5034
  acquire(): Promise<HttpClient>;
5025
5035
  release(client: HttpClient): Promise<void>;
5026
- request<T = any>(config: RequestConfig): Promise<HttpResponse<T>>;
5036
+ request<T = unknown, TData = unknown>(config: RequestConfig<TData>): Promise<HttpResponse<T>>;
5027
5037
  drain(): Promise<void>;
5028
5038
  clear(): Promise<void>;
5029
5039
  getStats(): PoolStats;
package/dist/index.d.ts CHANGED
@@ -1173,7 +1173,9 @@ declare enum RegistryEvent {
1173
1173
  /**
1174
1174
  * Event handler type
1175
1175
  */
1176
- type EventHandler = (data: any) => void;
1176
+ type EventHandler = (data: unknown) => void;
1177
+ type RegistryTool = Tool<unknown, unknown>;
1178
+ type RegisterManyTool = Tool<never, unknown>;
1177
1179
  /**
1178
1180
  * Options for generating tool prompts
1179
1181
  */
@@ -1250,7 +1252,7 @@ declare class ToolRegistry {
1250
1252
  * registry.register(readFileTool);
1251
1253
  * ```
1252
1254
  */
1253
- register(tool: Tool<any, any>): void;
1255
+ register<TInput, TOutput>(tool: Tool<TInput, TOutput>): void;
1254
1256
  /**
1255
1257
  * Get a tool by name
1256
1258
  *
@@ -1265,7 +1267,7 @@ declare class ToolRegistry {
1265
1267
  * }
1266
1268
  * ```
1267
1269
  */
1268
- get(name: string): Tool<any, any> | undefined;
1270
+ get(name: string): RegistryTool | undefined;
1269
1271
  /**
1270
1272
  * Check if a tool exists in the registry
1271
1273
  *
@@ -1306,7 +1308,7 @@ declare class ToolRegistry {
1306
1308
  * const updated = registry.update('read-file', newReadFileTool);
1307
1309
  * ```
1308
1310
  */
1309
- update(name: string, tool: Tool<any, any>): boolean;
1311
+ update<TInput, TOutput>(name: string, tool: Tool<TInput, TOutput>): boolean;
1310
1312
  /**
1311
1313
  * Get all registered tools
1312
1314
  *
@@ -1318,7 +1320,7 @@ declare class ToolRegistry {
1318
1320
  * console.log(`Total tools: ${allTools.length}`);
1319
1321
  * ```
1320
1322
  */
1321
- getAll(): Tool<any, any>[];
1323
+ getAll(): RegistryTool[];
1322
1324
  /**
1323
1325
  * Get tools by category
1324
1326
  *
@@ -1330,7 +1332,7 @@ declare class ToolRegistry {
1330
1332
  * const fileTools = registry.getByCategory(ToolCategory.FILE_SYSTEM);
1331
1333
  * ```
1332
1334
  */
1333
- getByCategory(category: ToolCategory): Tool<any, any>[];
1335
+ getByCategory(category: ToolCategory): RegistryTool[];
1334
1336
  /**
1335
1337
  * Get tools by tag
1336
1338
  *
@@ -1342,7 +1344,7 @@ declare class ToolRegistry {
1342
1344
  * const fileTools = registry.getByTag('file');
1343
1345
  * ```
1344
1346
  */
1345
- getByTag(tag: string): Tool<any, any>[];
1347
+ getByTag(tag: string): RegistryTool[];
1346
1348
  /**
1347
1349
  * Search tools by name or description
1348
1350
  *
@@ -1357,11 +1359,11 @@ declare class ToolRegistry {
1357
1359
  * // Returns tools with 'file' in name or description
1358
1360
  * ```
1359
1361
  */
1360
- search(query: string): Tool<any, any>[];
1362
+ search(query: string): RegistryTool[];
1361
1363
  /**
1362
1364
  * Register multiple tools at once
1363
1365
  *
1364
- * @param tools - Array of tools to register
1366
+ * @param tools - Iterable of tools to register
1365
1367
  * @throws Error if any tool name conflicts with existing tools
1366
1368
  *
1367
1369
  * @example
@@ -1369,7 +1371,7 @@ declare class ToolRegistry {
1369
1371
  * registry.registerMany([tool1, tool2, tool3]);
1370
1372
  * ```
1371
1373
  */
1372
- registerMany(tools: Tool<any, any>[]): void;
1374
+ registerMany(tools: Iterable<RegisterManyTool>): void;
1373
1375
  /**
1374
1376
  * Clear all tools from the registry
1375
1377
  *
@@ -1506,6 +1508,7 @@ declare class ToolRegistry {
1506
1508
  * @private
1507
1509
  */
1508
1510
  private formatRelations;
1511
+ private getSchemaShape;
1509
1512
  }
1510
1513
 
1511
1514
  /**
@@ -1525,14 +1528,14 @@ interface ToolExecutorConfig {
1525
1528
  maxConcurrent?: number;
1526
1529
  timeout?: number;
1527
1530
  retryPolicy?: RetryPolicy;
1528
- priorityFn?: (tool: any) => Priority$1;
1529
- onExecutionStart?: (tool: any, input: any) => void;
1530
- onExecutionComplete?: (tool: any, input: any, result: any, duration: number) => void;
1531
- onExecutionError?: (tool: any, input: any, error: Error, duration: number) => void;
1531
+ priorityFn?: (tool: ExecutableTool) => Priority$1;
1532
+ onExecutionStart?: (tool: ExecutableTool, input: unknown) => void;
1533
+ onExecutionComplete?: (tool: ExecutableTool, input: unknown, result: unknown, duration: number) => void;
1534
+ onExecutionError?: (tool: ExecutableTool, input: unknown, error: Error, duration: number) => void;
1532
1535
  }
1533
1536
  interface ToolExecution {
1534
- tool: any;
1535
- input: any;
1537
+ tool: ExecutableTool;
1538
+ input: unknown;
1536
1539
  priority?: Priority$1;
1537
1540
  }
1538
1541
  interface ExecutionMetrics {
@@ -1543,14 +1546,21 @@ interface ExecutionMetrics {
1543
1546
  averageDuration: number;
1544
1547
  byPriority: Record<Priority$1, number>;
1545
1548
  }
1549
+ interface ExecutableTool<TInput = unknown, TOutput = unknown> {
1550
+ metadata?: {
1551
+ name?: string;
1552
+ };
1553
+ invoke?: (input: TInput) => Promise<TOutput>;
1554
+ execute?: (input: TInput) => Promise<TOutput>;
1555
+ }
1546
1556
  /**
1547
1557
  * Create a tool executor with resource management
1548
1558
  */
1549
1559
  declare function createToolExecutor(config?: ToolExecutorConfig): {
1550
- execute: (tool: any, input: any, options?: {
1560
+ execute: (tool: ExecutableTool, input: unknown, options?: {
1551
1561
  priority?: Priority$1;
1552
- }) => Promise<any>;
1553
- executeParallel: (executions: ToolExecution[]) => Promise<any[]>;
1562
+ }) => Promise<unknown>;
1563
+ executeParallel: (executions: ToolExecution[]) => Promise<unknown[]>;
1554
1564
  getMetrics: () => ExecutionMetrics;
1555
1565
  resetMetrics: () => void;
1556
1566
  getQueueStatus: () => {
@@ -4986,22 +4996,22 @@ interface HttpPoolConfig extends PoolConfig {
4986
4996
  keepAliveMsecs?: number;
4987
4997
  }
4988
4998
  interface HttpClient {
4989
- get<T = any>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>;
4990
- post<T = any>(url: string, data?: any, config?: RequestConfig): Promise<HttpResponse<T>>;
4991
- put<T = any>(url: string, data?: any, config?: RequestConfig): Promise<HttpResponse<T>>;
4992
- delete<T = any>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>;
4993
- request<T = any>(config: RequestConfig): Promise<HttpResponse<T>>;
4999
+ get<T = unknown>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>;
5000
+ post<T = unknown, TData = unknown>(url: string, data?: TData, config?: RequestConfig<TData>): Promise<HttpResponse<T>>;
5001
+ put<T = unknown, TData = unknown>(url: string, data?: TData, config?: RequestConfig<TData>): Promise<HttpResponse<T>>;
5002
+ delete<T = unknown>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>;
5003
+ request<T = unknown, TData = unknown>(config: RequestConfig<TData>): Promise<HttpResponse<T>>;
4994
5004
  close(): Promise<void>;
4995
5005
  }
4996
- interface RequestConfig {
5006
+ interface RequestConfig<TData = unknown> {
4997
5007
  url?: string;
4998
5008
  method?: string;
4999
5009
  headers?: Record<string, string>;
5000
- params?: Record<string, any>;
5001
- data?: any;
5010
+ params?: Record<string, unknown>;
5011
+ data?: TData;
5002
5012
  timeout?: number;
5003
5013
  }
5004
- interface HttpResponse<T = any> {
5014
+ interface HttpResponse<T = unknown> {
5005
5015
  data: T;
5006
5016
  status: number;
5007
5017
  statusText: string;
@@ -5023,7 +5033,7 @@ declare class HttpPool {
5023
5033
  constructor(options: HttpPoolOptions);
5024
5034
  acquire(): Promise<HttpClient>;
5025
5035
  release(client: HttpClient): Promise<void>;
5026
- request<T = any>(config: RequestConfig): Promise<HttpResponse<T>>;
5036
+ request<T = unknown, TData = unknown>(config: RequestConfig<TData>): Promise<HttpResponse<T>>;
5027
5037
  drain(): Promise<void>;
5028
5038
  clear(): Promise<void>;
5029
5039
  getStats(): PoolStats;
package/dist/index.js CHANGED
@@ -686,6 +686,9 @@ Examples:`);
686
686
  return parts.join("\n");
687
687
  }
688
688
 
689
+ // src/tools/registry.ts
690
+ import { z as z3 } from "zod";
691
+
689
692
  // src/langgraph/observability/logger.ts
690
693
  var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
691
694
  LogLevel2["DEBUG"] = "debug";
@@ -790,6 +793,9 @@ var RegistryEvent = /* @__PURE__ */ ((RegistryEvent2) => {
790
793
  RegistryEvent2["REGISTRY_CLEARED"] = "registry:cleared";
791
794
  return RegistryEvent2;
792
795
  })(RegistryEvent || {});
796
+ function eraseToolType(tool) {
797
+ return tool;
798
+ }
793
799
  var ToolRegistry = class {
794
800
  tools = /* @__PURE__ */ new Map();
795
801
  eventHandlers = /* @__PURE__ */ new Map();
@@ -805,13 +811,14 @@ var ToolRegistry = class {
805
811
  * ```
806
812
  */
807
813
  register(tool) {
814
+ const erasedTool = eraseToolType(tool);
808
815
  const name = tool.metadata.name;
809
816
  if (this.tools.has(name)) {
810
817
  throw new Error(
811
818
  `Tool with name "${name}" is already registered. Use update() to modify it.`
812
819
  );
813
820
  }
814
- this.tools.set(name, tool);
821
+ this.tools.set(name, erasedTool);
815
822
  this.emit("tool:registered" /* TOOL_REGISTERED */, tool);
816
823
  }
817
824
  /**
@@ -882,6 +889,7 @@ var ToolRegistry = class {
882
889
  * ```
883
890
  */
884
891
  update(name, tool) {
892
+ const erasedTool = eraseToolType(tool);
885
893
  if (!this.tools.has(name)) {
886
894
  return false;
887
895
  }
@@ -890,7 +898,7 @@ var ToolRegistry = class {
890
898
  `Cannot update tool: metadata.name "${tool.metadata.name}" does not match registry key "${name}". To rename a tool, remove it and register it again with the new name.`
891
899
  );
892
900
  }
893
- this.tools.set(name, tool);
901
+ this.tools.set(name, erasedTool);
894
902
  this.emit("tool:updated" /* TOOL_UPDATED */, { name, tool });
895
903
  return true;
896
904
  }
@@ -964,7 +972,7 @@ var ToolRegistry = class {
964
972
  /**
965
973
  * Register multiple tools at once
966
974
  *
967
- * @param tools - Array of tools to register
975
+ * @param tools - Iterable of tools to register
968
976
  * @throws Error if any tool name conflicts with existing tools
969
977
  *
970
978
  * @example
@@ -973,9 +981,10 @@ var ToolRegistry = class {
973
981
  * ```
974
982
  */
975
983
  registerMany(tools) {
984
+ const toolsToRegister = Array.from(tools);
976
985
  const inputNames = /* @__PURE__ */ new Set();
977
986
  const duplicatesInInput = [];
978
- for (const tool of tools) {
987
+ for (const tool of toolsToRegister) {
979
988
  const name = tool.metadata.name;
980
989
  if (inputNames.has(name)) {
981
990
  duplicatesInInput.push(name);
@@ -989,7 +998,7 @@ var ToolRegistry = class {
989
998
  );
990
999
  }
991
1000
  const conflicts = [];
992
- for (const tool of tools) {
1001
+ for (const tool of toolsToRegister) {
993
1002
  if (this.tools.has(tool.metadata.name)) {
994
1003
  conflicts.push(tool.metadata.name);
995
1004
  }
@@ -999,7 +1008,7 @@ var ToolRegistry = class {
999
1008
  `Cannot register tools: the following names already exist: ${conflicts.join(", ")}`
1000
1009
  );
1001
1010
  }
1002
- for (const tool of tools) {
1011
+ for (const tool of toolsToRegister) {
1003
1012
  this.register(tool);
1004
1013
  }
1005
1014
  }
@@ -1262,13 +1271,14 @@ var ToolRegistry = class {
1262
1271
  return lines;
1263
1272
  }
1264
1273
  lines.push(`- ${metadata.name}: ${metadata.description}`);
1265
- const schemaShape = tool.schema._def?.shape?.();
1274
+ const schemaShape = this.getSchemaShape(tool.schema);
1266
1275
  if (schemaShape) {
1267
1276
  const params = Object.keys(schemaShape);
1268
1277
  if (params.length > 0) {
1269
1278
  const paramDescriptions = params.map((param) => {
1270
1279
  const field = schemaShape[param];
1271
- const type = field._def?.typeName?.replace("Zod", "").toLowerCase() || "any";
1280
+ const typeName = field._def.typeName;
1281
+ const type = typeName.replace("Zod", "").toLowerCase();
1272
1282
  return `${param} (${type})`;
1273
1283
  });
1274
1284
  lines.push(` Parameters: ${paramDescriptions.join(", ")}`);
@@ -1328,6 +1338,12 @@ var ToolRegistry = class {
1328
1338
  }
1329
1339
  return lines;
1330
1340
  }
1341
+ getSchemaShape(schema) {
1342
+ if (schema instanceof z3.ZodObject) {
1343
+ return schema.shape;
1344
+ }
1345
+ return void 0;
1346
+ }
1331
1347
  };
1332
1348
 
1333
1349
  // src/tools/executor.ts
@@ -1375,6 +1391,12 @@ function createToolExecutor(config = {}) {
1375
1391
  }
1376
1392
  return Math.min(delay, maxDelay);
1377
1393
  }
1394
+ function toError(error) {
1395
+ if (error instanceof Error) {
1396
+ return error;
1397
+ }
1398
+ return new Error(String(error));
1399
+ }
1378
1400
  async function executeWithRetry(tool, input, policy) {
1379
1401
  const executeFn = tool.invoke || tool.execute;
1380
1402
  if (!executeFn) {
@@ -1390,18 +1412,24 @@ function createToolExecutor(config = {}) {
1390
1412
  if (!policy) {
1391
1413
  return await executeFn.call(tool, input);
1392
1414
  }
1415
+ if (!Number.isInteger(policy.maxAttempts) || policy.maxAttempts < 1) {
1416
+ throw new Error(
1417
+ `Invalid retry policy: maxAttempts must be an integer >= 1 (received ${String(policy.maxAttempts)})`
1418
+ );
1419
+ }
1393
1420
  let lastError;
1394
1421
  for (let attempt = 1; attempt <= policy.maxAttempts; attempt++) {
1395
1422
  try {
1396
1423
  return await executeFn.call(tool, input);
1397
1424
  } catch (error) {
1398
- lastError = error;
1425
+ const currentError = toError(error);
1426
+ lastError = currentError;
1399
1427
  if (policy.retryableErrors && policy.retryableErrors.length > 0) {
1400
1428
  const isRetryable = policy.retryableErrors.some(
1401
- (msg) => lastError.message.includes(msg)
1429
+ (msg) => currentError.message.includes(msg)
1402
1430
  );
1403
1431
  if (!isRetryable) {
1404
- throw lastError;
1432
+ throw currentError;
1405
1433
  }
1406
1434
  }
1407
1435
  if (attempt < policy.maxAttempts) {
@@ -1410,7 +1438,7 @@ function createToolExecutor(config = {}) {
1410
1438
  }
1411
1439
  }
1412
1440
  }
1413
- throw lastError;
1441
+ throw lastError ?? new Error("Tool execution failed after retries");
1414
1442
  }
1415
1443
  async function executeSingle(tool, input, priority) {
1416
1444
  const startTime = Date.now();
@@ -1432,13 +1460,14 @@ function createToolExecutor(config = {}) {
1432
1460
  return result;
1433
1461
  } catch (error) {
1434
1462
  const duration = Date.now() - startTime;
1463
+ const normalizedError = toError(error);
1435
1464
  metrics.totalExecutions++;
1436
1465
  metrics.failedExecutions++;
1437
1466
  metrics.totalDuration += duration;
1438
1467
  metrics.averageDuration = metrics.totalDuration / metrics.totalExecutions;
1439
1468
  metrics.byPriority[priority]++;
1440
- onExecutionError?.(tool, input, error, duration);
1441
- throw error;
1469
+ onExecutionError?.(tool, input, normalizedError, duration);
1470
+ throw normalizedError;
1442
1471
  }
1443
1472
  }
1444
1473
  async function processQueue() {
@@ -1900,8 +1929,8 @@ function createToolSimulator(config) {
1900
1929
  if (!latency) return 0;
1901
1930
  const u1 = Math.random();
1902
1931
  const u2 = Math.random();
1903
- const z3 = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
1904
- return Math.max(0, latency.mean + z3 * latency.stddev);
1932
+ const z4 = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
1933
+ return Math.max(0, latency.mean + z4 * latency.stddev);
1905
1934
  }
1906
1935
  return {
1907
1936
  execute: async (toolName, input) => {
@@ -4329,8 +4358,8 @@ function createDatabasePool(options) {
4329
4358
 
4330
4359
  // src/resources/http-pool.ts
4331
4360
  var MockHttpClient = class {
4332
- constructor(config) {
4333
- this.config = config;
4361
+ constructor(_config) {
4362
+ this._config = _config;
4334
4363
  }
4335
4364
  closed = false;
4336
4365
  async get(url, config) {
@@ -4345,7 +4374,7 @@ var MockHttpClient = class {
4345
4374
  async delete(url, config) {
4346
4375
  return this.request({ ...config, url, method: "DELETE" });
4347
4376
  }
4348
- async request(config) {
4377
+ async request(_config) {
4349
4378
  if (this.closed) {
4350
4379
  throw new Error("Client is closed");
4351
4380
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentforge/core",
3
- "version": "0.15.3",
3
+ "version": "0.15.5",
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",