@wavequery/conductor
Version:
Modular LLM orchestration framework
77 lines • 2.55 kB
JavaScript
import { EventEmitter } from "events";
import { Agent } from "@/agents/agent";
export class Workflow extends EventEmitter {
constructor(config) {
super();
this.agents = new Map();
this.executionOrder = [];
this.config = config;
this.initializeAgents();
this.computeExecutionOrder();
}
initializeAgents() {
for (const agentConfig of this.config.agents) {
this.agents.set(agentConfig.name, new Agent(agentConfig));
}
}
computeExecutionOrder() {
// Simple topological sort for now
const visited = new Set();
const temp = new Set();
const order = [];
const visit = (node) => {
if (temp.has(node)) {
throw new Error("Workflow has cycles");
}
if (visited.has(node))
return;
temp.add(node);
const edges = this.config.graph.edges.filter((e) => e.from === node);
for (const edge of edges) {
visit(edge.to);
}
temp.delete(node);
visited.add(node);
order.unshift(node);
};
for (const node of this.config.graph.nodes) {
if (!visited.has(node)) {
visit(node);
}
}
this.executionOrder = order;
}
async execute(input) {
const results = {};
const cache = { input };
for (const agentName of this.executionOrder) {
const agent = this.agents.get(agentName);
// Prepare input from previous steps
const agentInput = this.prepareInput(agentName, cache);
// Execute agent
try {
const result = await agent.execute(agentInput);
results[agentName] = result;
cache[agentName] = result.output;
this.emit("agentComplete", { agent: agentName, result });
}
catch (error) {
this.emit("error", { agent: agentName, error });
throw error;
}
}
return results;
}
prepareInput(agentName, cache) {
const incomingEdges = this.config.graph.edges.filter((e) => e.to === agentName);
if (incomingEdges.length === 0) {
return cache.input;
}
const input = {};
for (const edge of incomingEdges) {
input[edge.from] = cache[edge.from];
}
return input;
}
}
//# sourceMappingURL=workflow.js.map