UNPKG

@agent-graph/core

Version:

A lightweight AI Agent orchestration solution

126 lines (125 loc) 5.1 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; /** * Lifecycle: run(init) -> superstep() -> interrupt() -> superstep() -> exit() -> ... -> shutdown() * */ export class BuiltGraph { constructor({ builder, context, checkpointer, }) { var _a; this.running = false; this.version = 1; this.interruptVectorTable = []; this.shutdownHooks = []; this.computedListeners = []; this.context = context; this.builder = builder; this.checkpointer = checkpointer; (_a = this.checkpointer) === null || _a === void 0 ? void 0 : _a.setVersion(this.version); // runtime methods this.exit = this.exit.bind(this); this.interrupt = this.interrupt.bind(this); this.addShutdownHook = this.addShutdownHook.bind(this); } // todo: priority queue ... interrupt(interrupt) { this.interruptVectorTable.push(interrupt); } exit(status) { this.running = false; } addShutdownHook(hook) { this.shutdownHooks.push(hook); } shutdown() { return __awaiter(this, void 0, void 0, function* () { const hook = this.shutdownHooks.pop(); if (!hook) return; yield hook(); }); } get runtime() { return { context: this.context, version: this.version, exit: this.exit, interrupt: this.interrupt, addShutdownHook: this.addShutdownHook, }; } onComputed(listener) { this.computedListeners.push(listener); } activeAllVertices() { for (const vertex of this.builder.vertices.values()) { vertex.active(); } } setVertexStates(states) { for (const [id, state] of Object.entries(states)) { const vertex = this.builder.vertices.get(id); vertex === null || vertex === void 0 ? void 0 : vertex.setState(state); } } getVertexStates() { const states = {}; for (const vertex of this.builder.vertices.values()) { states[vertex.id] = vertex.state; } return states; } // single vertex compute compute(vertexId, inputProps) { return __awaiter(this, void 0, void 0, function* () { const vertex = this.builder.vertices.get(vertexId); if (!vertex) return []; const getOutEdges = this.builder.edges.get(vertex.id); const props = yield vertex.compute(inputProps, this.runtime); this.computedListeners.forEach((listener) => listener(vertexId, props)); const edges = getOutEdges ? (yield getOutEdges(props, vertex.state, this.runtime)).map((v) => v.id) : []; if (vertex.isWaiting) { return [{ next: vertexId, props: inputProps }]; } const steps = edges.map((next) => ({ next, props })); return steps; }); } superstep(state) { return __awaiter(this, void 0, void 0, function* () { const promises = state.map(({ next, props }) => this.compute(next, props)); return (yield Promise.all(promises)).flat(); }); } run(initialSteps_1) { return __awaiter(this, arguments, void 0, function* (initialSteps, initialStates = {}) { var _a; this.running = true; let steps = initialSteps; this.setVertexStates(initialStates); this.activeAllVertices(); while (steps.length !== 0) { // filter active vertices const activeSteps = steps.filter(({ next }) => { var _a; return (_a = this.builder.vertices.get(next)) === null || _a === void 0 ? void 0 : _a.isActive; }); const otherSteps = steps.filter(({ next }) => { var _a; return !((_a = this.builder.vertices.get(next)) === null || _a === void 0 ? void 0 : _a.isActive); }); if (activeSteps.length === 0) break; const nextSteps = yield this.superstep(activeSteps); steps = [...nextSteps, ...otherSteps]; yield ((_a = this.checkpointer) === null || _a === void 0 ? void 0 : _a.save(steps, this.getVertexStates())); if (!this.running) break; } yield this.shutdown(); }); } }