How Egonex-AI Defines Nodes and Edges in Its Knowledge Graph Schema for Code Entities
Egonex-AI's Understand-Anything project defines nodes as typed code entities with UUIDs and metadata, and edges as directed relationships between them, both declared in TypeScript interfaces in packages/core/src/types.ts.
The Egonex-AI Understand-Anything repository transforms raw source code into a queryable structure governed by a knowledge graph schema for code entities. This schema, defined in TypeScript within the packages/core/src/types.ts module, strictly types both nodes and edges to enable accurate cross-language code analysis. The following sections dissect the exact interface definitions and architectural patterns that convert software syntax into traversable graph relationships.
Node Structure in the Knowledge Graph Schema
Nodes represent discrete code entities such as files, classes, functions, and variables. According to the source code in packages/core/src/types.ts, each node implements a mandatory set of properties that ensure unique identification and traceability back to specific source locations.
Core Node Properties
The Node interface requires the following fields:
id: A globally unique UUID assigned to every entitytype: The high-level category (e.g.,file,class,function,variable,test)name: The human-readable identifier of the entitypath: Relative filesystem path to the source filerange: An object containingstartandendline numbers locating the entitylanguage: Programming language identifier (e.g.,typescript,python,go)metadata: Optional JSON blob for language-specific details like signatures or docstringstags: Optional array of strings for filtering (e.g.,public,private,test)
export interface Node {
id: string;
type: string;
name: string;
path: string;
range: { start: number; end: number };
language: string;
metadata?: Record<string, unknown>;
tags?: string[];
}
Edge Structure and Relationship Types
Edges capture directional relationships between nodes, such as function calls, imports, inheritance, or containment. The Edge interface, defined alongside Node in packages/core/src/types.ts, establishes the connection semantics using source and target UUID references.
Edge Interface Definition
Each edge connects exactly two nodes through these properties:
source: UUID of the origin node where the relationship originatestarget: UUID of the destination node where the relationship pointstype: Relationship category (e.g.,call,import,inheritance,containment)label: Optional human-readable description for visualizationmetadata: Optional JSON object for additional context like call-site line numbers
export interface Edge {
source: string;
target: string;
type: string;
label?: string;
metadata?: Record<string, unknown>;
}
How the Schema Powers Code Analysis
The static type definitions drive a multi-stage pipeline that converts abstract syntax tree (AST) fragments into a persistent, queryable knowledge graph.
Entity Extraction via Tree-Sitter
The packages/core/src/plugins/tree-sitter-plugin.ts implements language-specific AST walkers. These parsers traverse source files and instantiate Node objects for each discovered entity, populating the range and language fields based on concrete syntax tree positions.
Graph Construction and Edge Resolution
After node collection, the packages/core/src/analyzer/graph-builder.ts performs semantic analysis to create Edge instances. It identifies relationships through static analysis of imports, class inheritance chains, and function call graphs, mapping each relationship to the canonical source and target UUIDs defined in the schema.
Persistence and Indexing
The assembled graph serializes to .understand-anything/knowledge-graph.json. The packages/core/src/search.ts module indexes node metadata to enable full-text queries against the code graph, while packages/dashboard/src/utils/edgeAggregation.ts handles client-side merging of duplicate edges for visual clarity.
Practical Code Examples
Creating a Node Programmatically
import { Node } from '@understand-anything/core';
const fnNode: Node = {
id: 'node-12345',
type: 'function',
name: 'calculateTotal',
path: 'src/utils/math.ts',
range: { start: 42, end: 58 },
language: 'typescript',
metadata: { signature: '(prices: number[]) => number' },
tags: ['public']
};
Defining a Relationship Edge
import { Edge } from '@understand-anything/core';
const callEdge: Edge = {
source: 'node-12345', // calculateTotal
target: 'node-67890', // sumArray
type: 'call',
label: 'calls',
metadata: { line: 45 } // line where call occurs
};
Persisting the Knowledge Graph
import { writeFile } from 'fs/promises';
import { Graph } from '@understand-anything/core';
const graph: Graph = {
nodes: [fnNode, otherNode],
edges: [callEdge, importEdge]
};
await writeFile('.understand-anything/knowledge-graph.json', JSON.stringify(graph, null, 2));
Querying the Graph
import { search } from '@understand-anything/core/search';
const results = await search('function:calculateTotal', { limit: 10 });
console.log(results); // Array of matching Node objects
Key Implementation Files
These source files define and utilize the knowledge graph schema:
packages/core/src/types.ts: Central TypeScript definitions forNodeandEdgeinterfacespackages/core/src/analyzer/graph-builder.ts: Logic that assembles nodes and derives edges from semantic analysispackages/core/src/plugins/tree-sitter-plugin.ts: AST walker that extracts entities from source files and createsNodeinstancespackages/core/src/search.ts: Full-text search engine that indexes node metadata for fast lookupspackages/dashboard/src/utils/edgeAggregation.ts: Client-side utility for merging duplicate edges in visualizations
Summary
- Nodes represent code entities with UUID-based identity, typed categorization, and source location tracking via the
Nodeinterface inpackages/core/src/types.ts - Edges model directed relationships using
sourceandtargetUUID references, with optional labels and metadata for context - The Tree-Sitter plugin handles initial node extraction from language-specific ASTs
- The graph-builder resolves semantic relationships to instantiate edges between related entities
- The search module indexes the graph for fast code navigation and querying
- Both nodes and edges support extensible metadata fields for language-specific details without breaking the core schema
Frequently Asked Questions
What identifier format does Egonex-AI use for knowledge graph nodes?
The system assigns each node a globally unique UUID stored in the required id field. This immutable identifier ensures stable references across the graph regardless of file renames or code refactoring operations.
Can the schema handle relationships across different programming languages?
Yes. The language property on nodes tags entities by their source language, while edges connect nodes based on semantic relationships like import or call. The packages/core/src/analyzer/graph-builder.ts handles cross-language resolution when analyzing polyglot repositories.
How does the system distinguish between public and private code entities?
The optional tags array on nodes accepts string values like public or private. These tags filter query results and visualization views without requiring changes to the core TypeScript interfaces.
Where does Understand-Anything store the constructed knowledge graph?
After analysis, the graph serializes to .understand-anything/knowledge-graph.json in the project root. The dashboard and search APIs read from this JSON file to serve the code exploration interface.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →