Skip to content

Commit a44ffe7

Browse files
committedDec 8, 2024
feat: add toolLoader
1 parent 6b51594 commit a44ffe7

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed
 

‎src/core/toolLoader.ts

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { BaseTool } from "../tools/BaseTool.js";
2+
import { fileURLToPath } from "url";
3+
import { dirname, join } from "path";
4+
import { promises as fs } from "fs";
5+
6+
export interface ToolLoaderOptions {
7+
toolsDir?: string;
8+
exclude?: string[];
9+
}
10+
11+
export class ToolLoader {
12+
private toolsDir: string;
13+
private exclude: string[];
14+
15+
constructor(options: ToolLoaderOptions = {}) {
16+
this.exclude = options.exclude || ["BaseTool.js", "*.test.js", "*.spec.js"];
17+
this.toolsDir = options.toolsDir || this.findDefaultToolsDir();
18+
}
19+
20+
private findDefaultToolsDir(): string {
21+
const currentFilePath = fileURLToPath(import.meta.url);
22+
const currentDir = dirname(currentFilePath);
23+
return join(currentDir, "..", "..", "dist", "tools");
24+
}
25+
26+
private isToolFile(file: string): boolean {
27+
if (!file.endsWith(".js")) return false;
28+
return !this.exclude.some((pattern) => {
29+
if (pattern.includes("*")) {
30+
const regex = new RegExp(pattern.replace("*", ".*"));
31+
return regex.test(file);
32+
}
33+
return file === pattern;
34+
});
35+
}
36+
37+
private validateTool(tool: any): tool is BaseTool {
38+
return Boolean(
39+
tool &&
40+
typeof tool.name === "string" &&
41+
tool.toolDefinition &&
42+
typeof tool.toolCall === "function"
43+
);
44+
}
45+
46+
async loadTools(): Promise<BaseTool[]> {
47+
try {
48+
const files = await fs.readdir(this.toolsDir);
49+
50+
const toolPromises = files
51+
.filter((file) => this.isToolFile(file))
52+
.map(async (file) => {
53+
try {
54+
const modulePath = `file://${join(this.toolsDir, file)}`;
55+
const { default: ToolClass } = await import(modulePath);
56+
57+
if (!ToolClass) return null;
58+
59+
const tool = new ToolClass();
60+
return this.validateTool(tool) ? tool : null;
61+
} catch {
62+
return null;
63+
}
64+
});
65+
66+
const tools = (await Promise.all(toolPromises)).filter(
67+
Boolean
68+
) as BaseTool[];
69+
return tools;
70+
} catch (error) {
71+
console.error(`Failed to load tools from ${this.toolsDir}`);
72+
return [];
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)
Please sign in to comment.