@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 +48 -19
- package/dist/index.d.cts +39 -29
- package/dist/index.d.ts +39 -29
- package/dist/index.js +48 -19
- package/package.json +1 -1
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,
|
|
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,
|
|
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 -
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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) =>
|
|
1604
|
+
(msg) => currentError.message.includes(msg)
|
|
1577
1605
|
);
|
|
1578
1606
|
if (!isRetryable) {
|
|
1579
|
-
throw
|
|
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,
|
|
1616
|
-
throw
|
|
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
|
|
2079
|
-
return Math.max(0, latency.mean +
|
|
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(
|
|
4508
|
-
this.
|
|
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(
|
|
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:
|
|
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<
|
|
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):
|
|
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<
|
|
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():
|
|
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):
|
|
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):
|
|
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):
|
|
1362
|
+
search(query: string): RegistryTool[];
|
|
1361
1363
|
/**
|
|
1362
1364
|
* Register multiple tools at once
|
|
1363
1365
|
*
|
|
1364
|
-
* @param tools -
|
|
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:
|
|
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:
|
|
1529
|
-
onExecutionStart?: (tool:
|
|
1530
|
-
onExecutionComplete?: (tool:
|
|
1531
|
-
onExecutionError?: (tool:
|
|
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:
|
|
1535
|
-
input:
|
|
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:
|
|
1560
|
+
execute: (tool: ExecutableTool, input: unknown, options?: {
|
|
1551
1561
|
priority?: Priority$1;
|
|
1552
|
-
}) => Promise<
|
|
1553
|
-
executeParallel: (executions: ToolExecution[]) => Promise<
|
|
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 =
|
|
4990
|
-
post<T =
|
|
4991
|
-
put<T =
|
|
4992
|
-
delete<T =
|
|
4993
|
-
request<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,
|
|
5001
|
-
data?:
|
|
5010
|
+
params?: Record<string, unknown>;
|
|
5011
|
+
data?: TData;
|
|
5002
5012
|
timeout?: number;
|
|
5003
5013
|
}
|
|
5004
|
-
interface HttpResponse<T =
|
|
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 =
|
|
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:
|
|
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<
|
|
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):
|
|
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<
|
|
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():
|
|
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):
|
|
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):
|
|
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):
|
|
1362
|
+
search(query: string): RegistryTool[];
|
|
1361
1363
|
/**
|
|
1362
1364
|
* Register multiple tools at once
|
|
1363
1365
|
*
|
|
1364
|
-
* @param tools -
|
|
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:
|
|
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:
|
|
1529
|
-
onExecutionStart?: (tool:
|
|
1530
|
-
onExecutionComplete?: (tool:
|
|
1531
|
-
onExecutionError?: (tool:
|
|
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:
|
|
1535
|
-
input:
|
|
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:
|
|
1560
|
+
execute: (tool: ExecutableTool, input: unknown, options?: {
|
|
1551
1561
|
priority?: Priority$1;
|
|
1552
|
-
}) => Promise<
|
|
1553
|
-
executeParallel: (executions: ToolExecution[]) => Promise<
|
|
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 =
|
|
4990
|
-
post<T =
|
|
4991
|
-
put<T =
|
|
4992
|
-
delete<T =
|
|
4993
|
-
request<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,
|
|
5001
|
-
data?:
|
|
5010
|
+
params?: Record<string, unknown>;
|
|
5011
|
+
data?: TData;
|
|
5002
5012
|
timeout?: number;
|
|
5003
5013
|
}
|
|
5004
|
-
interface HttpResponse<T =
|
|
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 =
|
|
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,
|
|
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,
|
|
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 -
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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) =>
|
|
1429
|
+
(msg) => currentError.message.includes(msg)
|
|
1402
1430
|
);
|
|
1403
1431
|
if (!isRetryable) {
|
|
1404
|
-
throw
|
|
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,
|
|
1441
|
-
throw
|
|
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
|
|
1904
|
-
return Math.max(0, latency.mean +
|
|
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(
|
|
4333
|
-
this.
|
|
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(
|
|
4377
|
+
async request(_config) {
|
|
4349
4378
|
if (this.closed) {
|
|
4350
4379
|
throw new Error("Client is closed");
|
|
4351
4380
|
}
|
package/package.json
CHANGED