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 entity
  • type: The high-level category (e.g., file, class, function, variable, test)
  • name: The human-readable identifier of the entity
  • path: Relative filesystem path to the source file
  • range: An object containing start and end line numbers locating the entity
  • language: Programming language identifier (e.g., typescript, python, go)
  • metadata: Optional JSON blob for language-specific details like signatures or docstrings
  • tags: 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 originates
  • target: UUID of the destination node where the relationship points
  • type: Relationship category (e.g., call, import, inheritance, containment)
  • label: Optional human-readable description for visualization
  • metadata: 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:

Summary

  • Nodes represent code entities with UUID-based identity, typed categorization, and source location tracking via the Node interface in packages/core/src/types.ts
  • Edges model directed relationships using source and target UUID 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →