@wavequery/conductor
Version:
Modular LLM orchestration framework
117 lines • 3.66 kB
JavaScript
import { EventEmitter } from "events";
export class Agent extends EventEmitter {
constructor(config) {
super();
this.steps = [];
this.startTime = 0;
this.config = {
maxIterations: 1,
defaultTimeout: 15000,
...config,
};
}
async execute(input) {
this.startTime = Date.now();
this.steps = [];
try {
const output = await this.runAgentLoop(input);
return this.createResponse(output);
}
catch (error) {
this.emit("error", error);
throw error;
}
}
async runAgentLoop(input) {
let iteration = 0;
let currentInput = input;
while (iteration < this.config.maxIterations) {
const step = await this.executeStep(currentInput);
this.steps.push(step);
this.emit("step", step);
if (step.error) {
throw step.error;
}
currentInput = step.output;
iteration++;
if (this.shouldStop(step)) {
break;
}
}
return { output: currentInput, steps: this.steps };
}
async executeStep(input) {
const startTime = Date.now();
try {
const { action, toolName } = await this.decideTool(input);
const tool = this.getTool(toolName);
const output = await tool.execute(action);
return {
type: "tool",
name: toolName,
input: action,
output,
timestamp: new Date(),
duration: Date.now() - startTime,
};
}
catch (error) {
return {
type: "tool",
name: "error",
input,
output: null,
error: error,
timestamp: new Date(),
duration: Date.now() - startTime,
};
}
}
async decideTool(input) {
const prompt = this.createToolSelectionPrompt(input);
const response = await this.config.llmProvider.complete(prompt);
try {
const decision = JSON.parse(response.content);
return {
action: decision.action,
toolName: decision.tool,
};
}
catch (error) {
throw new Error("Failed to parse tool decision");
}
}
getTool(name) {
const tool = this.config.tools.find((t) => t.name === name);
if (!tool) {
throw new Error(`Tool ${name} not found`);
}
return tool;
}
createToolSelectionPrompt(input) {
const tools = this.config.tools.map((t) => ({
name: t.name,
description: t.description,
tool_arguments: t.input,
}));
return `Given the following input: ${JSON.stringify(input)}
Available tools: ${JSON.stringify(tools)}
Select the most appropriate tool and specify the action.
Response format: { "tool": "tool_name", "action": "arguments to be passed to the tool" }`;
}
shouldStop(step) {
return false;
}
createResponse(response) {
return {
output: response.output,
steps: response.steps,
metrics: {
totalTokens: 0, // TODO: Implement token counting
totalCost: 0, // TODO: Implement cost calculation
duration: Date.now() - this.startTime,
},
};
}
}
//# sourceMappingURL=agent.js.map