agentlang
Version:
The easiest way to build the most reliable AI agents - enterprise-grade teams of AI agents that collaborate with each other and humans
156 lines • 4.84 kB
JavaScript
import { fetchModule, getModuleNames } from './module.js';
import { DefaultModuleName, Path } from './util.js';
function asEdgeEntry(rge) {
const nm = new Map();
nm.set(rge.node.entity.asFqName(), rge.node.edges.map(asEdgeEntry));
const e = {
relationship: rge.relationship.getFqName(),
type: rge.relationship.isContains() ? 'contains' : 'between',
to: Object.fromEntries(nm),
};
return e;
}
export class RelationshipGraph {
constructor(nodes) {
this.nodes = nodes;
}
getRoots() {
return this.nodes;
}
asObject() {
const result = new Map();
this.nodes.forEach((node) => {
result.set(node.entity.asFqName(), node.edges.map(asEdgeEntry));
});
return Object.fromEntries(result);
}
walkEdges(node, onNode, onContainsRelationship, onBetweenRelationship) {
const n = node.entity.asFqName();
onNode(n, node.edges);
node.edges.forEach((edge) => {
const rf = edge.relationship.isContains()
? onContainsRelationship
: onBetweenRelationship;
rf(n, edge.node.entity.asFqName(), edge.relationship);
this.walkEdges(edge.node, onNode, onContainsRelationship, onBetweenRelationship);
});
}
walk(onNode, onContainsRelationship, onBetweenRelationship) {
this.nodes.forEach((node) => {
this.walkEdges(node, onNode, onContainsRelationship, onBetweenRelationship);
});
}
}
const NullEdge = [];
const EmptyGraph = new RelationshipGraph(new Array());
export function buildGraph(moduleName) {
if (moduleName == DefaultModuleName)
return EmptyGraph;
const rootEnts = new Set();
const inRels = new Set();
const nodes = [];
let localMod;
getModuleNames().forEach((n) => {
const m = fetchModule(n);
if (n == moduleName)
localMod = m;
const rels = m.getRelationshipEntries();
rels.forEach((re) => {
const n1 = re.parentNode();
const n2 = re.childNode();
if (n1.path.getModuleName() == moduleName) {
const nn = n1.path.getEntryName();
if (!inRels.has(nn))
rootEnts.add(nn);
if (n2.path.getModuleName() == moduleName) {
const en = n2.path.getEntryName();
if (rootEnts.has(en)) {
rootEnts.delete(en);
}
if (re.isContains())
inRels.add(en);
}
const node = forceFindNode(nodes, n1.path);
connectEdge(node, re);
}
else if (n2.path.getModuleName() == moduleName) {
const en = n2.path.getEntryName();
inRels.add(en);
const node = forceFindNode(nodes, n1.path);
connectEdge(node, re);
}
});
});
if (localMod === undefined) {
throw new Error(`Failed to find module ${moduleName}`);
}
const remEnts = new Set();
const entityNames = localMod.getEntityNames();
for (const name of entityNames) {
if (!inRels.has(name)) {
remEnts.add(name);
}
}
remEnts.forEach((n) => {
if (!rootEnts.has(n)) {
const rn = {
entity: new Path(moduleName, n),
edges: NullEdge,
};
nodes.push(rn);
}
});
return new RelationshipGraph(nodes);
}
function forceFindNode(nodes, path) {
for (let i = 0; i < nodes.length; ++i) {
const n = nodes[i];
if (n.entity.equals(path)) {
return n;
}
else {
const n0 = findNodeInEdges(n.edges, path);
if (n0)
return n0;
}
}
const n = {
entity: path,
edges: NullEdge,
};
nodes.push(n);
return n;
}
function findNodeInEdges(edges, path) {
for (let i = 0; i < edges.length; ++i) {
const e = edges[i];
if (e.node.entity.equals(path)) {
return e.node;
}
const r = findNodeInEdges(e.node.edges, path);
if (r)
return r;
}
return undefined;
}
function connectEdge(node, re) {
const cn = re.childNode();
const n = {
entity: cn.path,
edges: NullEdge,
};
const e = {
relationship: re,
node: n,
};
if (node.edges == NullEdge) {
node.edges = new Array();
}
node.edges.push(e);
}
export function findEdgeForRelationship(relName, moduleName, edges) {
return edges.find((v) => {
return v.relationship.moduleName == moduleName && v.relationship.name == relName;
});
}
//# sourceMappingURL=relgraph.js.map