taskforce-aiagent
Version:
TaskForce is a modular, open-source, production-ready TypeScript agent framework for orchestrating AI agents, LLM-powered autonomous agents, task pipelines, dynamic toolchains, RAG workflows and memory/retrieval systems.
150 lines (149 loc) • 5.73 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ToolExecutor = void 0;
const lru_helper_js_1 = require("../../helpers/lru.helper.js");
const dotenv_1 = __importDefault(require("dotenv"));
dotenv_1.default.config();
class ToolExecutor {
constructor(tools, taskForce, agentName) {
this.tools = tools;
this.taskForce = taskForce;
this.agentName = agentName;
this.cache = (0, lru_helper_js_1.getToolCache)();
}
setTaskForce(taskForce) {
this.taskForce = taskForce;
}
getTools() {
return this.tools;
}
getToolNameById(toolId) {
return this.tools.find((t) => t.id === toolId)?.name || toolId;
}
buildToolUsageExamples(tools) {
return tools
.map((tool) => {
const paramDescriptions = this.buildDetailedParameterBlock(tool);
const example = this.buildExampleUsage(tool);
return `- ${tool.id}\n - Purpose: ${tool.description}\n${paramDescriptions}\n - Example ${tool.name} Usage:\n${example}`;
})
.join("\n\n");
}
buildDetailedParameterBlock(tool) {
if (!tool.parameters?.properties)
return "";
const topLevelRequired = tool.parameters.required ?? [];
const plural = Object.keys(tool.parameters.properties).length > 1
? "Parameters"
: "Parameter";
const renderField = (key, def, indent = 2, parentRequired = []) => {
const pad = " ".repeat(indent);
const isRequired = parentRequired.includes(key);
let line = `${pad}- ${key} (${def.type})${isRequired ? " [required]" : ""}`;
if (def.description)
line += `: ${def.description}`;
if (def.type === "object" && def.properties) {
const nestedRequired = def.required ?? [];
const nested = Object.entries(def.properties)
.map(([k, v]) => renderField(k, v, indent + 2, nestedRequired))
.join("\n");
line += `\n${nested}`;
}
else if (def.type === "array" && def.items) {
line += `\n${pad} items:`;
line += `\n${renderField("item", def.items, indent + 4, def.items.required ?? [])}`;
}
return line;
};
const lines = Object.entries(tool.parameters.properties).map(([k, v]) => renderField(k, v, 2, topLevelRequired));
return ` - ${plural}:\n${lines.join("\n")}`;
}
buildExampleUsage(tool) {
if (!tool.parameters || !tool.parameters.properties)
return `TOOL(${tool.id}, {})`;
const args = {};
for (const [key, def] of Object.entries(tool.parameters.properties)) {
if (def.example !== undefined) {
args[key] = def.example;
}
else {
switch (def.type) {
case "string":
args[key] = "example";
break;
case "number":
args[key] = 0;
break;
case "boolean":
args[key] = false;
break;
default:
args[key] = "value";
}
}
}
return `TOOL(${tool.id}, ${JSON.stringify(args)})`;
}
isValidInput(input, schema) {
if (!schema.required)
return true;
switch (schema.type) {
case "string":
return typeof input === "string";
case "number":
return typeof input === "number" && !isNaN(input);
case "object":
return (typeof input === "object" && input !== null && !Array.isArray(input));
default:
return false;
}
}
async executeToolById(toolId, args) {
const tool = this.tools.find((t) => t.id === toolId);
if (!tool)
return `⚠️ Tool '${toolId}' not found.`;
if (!this.isValidInput(args, tool.inputSchema)) {
return `⚠️ Invalid input for tool '${toolId}': expected ${tool.inputSchema.type}`;
}
const cacheKey = `${toolId}::${JSON.stringify(args)}`;
if (tool.cacheable) {
const cached = this.cache.get(cacheKey);
if (cached) {
return `🧠 (tool cached) ${cached}`;
}
}
try {
const result = await tool.handler(args);
// Optional caching
if (tool.cacheable) {
const shouldCache = tool.cacheFunction
? tool.cacheFunction(args, result)
: true;
if (shouldCache) {
this.cache.set(cacheKey, result);
}
}
const emitting = process.env.EMITTING;
if (emitting === "true") {
this.taskForce?.emitStep({
action: "tool_executed",
agent: this.agentName,
tool: tool.id,
toolPayload: args,
result,
});
}
return result;
}
catch (err) {
if (typeof tool.errorHandler === "function") {
return tool.errorHandler(err);
}
return `❌ Tool '${toolId}' execution error: ${err.message}`;
}
}
}
exports.ToolExecutor = ToolExecutor;