NeoGraph 0.16.0
A C++20 Graph Agent Engine Library — LangGraph for C++
Loading...
Searching...
No Matches
neograph::graph::GraphCompiler Class Reference

Stateless JSON parser and node-instantiation linker. More...

#include <compiler.h>

Static Public Member Functions

static json canon (const json &definition)
 Canonicalize a topology JSON document for equivalence comparison.
 
static CompiledGraph compile (const json &definition, const NodeContext &default_context)
 Parse a JSON graph definition into a CompiledGraph.
 
static CompiledGraph compile (const json &definition, const NodeContext &default_context, const GraphRegistry &registry)
 Compile with a local-first registry overlay.
 
static CompiledGraph compile_local (const json &definition, const NodeContext &default_context, const GraphRegistry &registry)
 Parse and link without process-global registry fallback.
 
static CompiledGraph link (TopologySpec topology, const NodeContext &default_context)
 Instantiate runtime nodes from an already parsed topology.
 
static CompiledGraph link (TopologySpec topology, const NodeContext &default_context, const GraphRegistry &registry)
 Instantiate nodes using a local-first registry overlay.
 
static CompiledGraph link_local (TopologySpec topology, const NodeContext &default_context, const GraphRegistry &registry)
 Instantiate nodes exclusively through the registry instance.
 
static TopologySpec parse (const json &definition)
 Parse JSON into a declarative topology without creating nodes.
 
static TopologySpec parse (const json &definition, const GraphRegistry &registry)
 Pure parse using a local-first registry for schema metadata.
 
static TopologySpec parse_local (const json &definition, const GraphRegistry &registry)
 Pure parse that rejects every executable absent from the registry instance.
 
static ParseReport parse_local_report (const json &definition, const GraphRegistry &registry)
 Total pure parse requiring every executable in the local registry.
 
static ParseReport parse_report (const json &definition, const GraphRegistry &registry)
 Total pure parse using local-first registry metadata.
 
static json upgrade_to_latest (const json &definition)
 Upgrade a legacy (schema_version 0 / absent) topology document to the current schema version.
 
static void verify_roundtrip (const json &definition, const CompiledGraph &cg)
 Translation validation: assert compile() lost nothing.
 
static void verify_roundtrip (const json &definition, const TopologySpec &topology)
 Translation validation before runtime node instantiation.
 
static RoundTripReport verify_roundtrip_report (const json &definition, const TopologySpec &topology)
 Total translation-validation before runtime node instantiation.
 

Detailed Description

Stateless JSON parser and node-instantiation linker.

parse() is the pure declarative boundary; link() creates GraphNode instances. compile() remains the compatibility composition of both operations.

Definition at line 250 of file compiler.h.

Member Function Documentation

◆ canon()

static json neograph::graph::GraphCompiler::canon ( const json &  definition)
static

Canonicalize a topology JSON document for equivalence comparison.

Pure function; no registries touched.

Two topology documents describe the same graph iff their canon() forms are equal (nlohmann object comparison is key-order insensitive; canon sorts all owned arrays). Used as the translation-validation oracle: canon(definition) == canon(compile(definition).to_json())

Normalizations applied (the whitelist — anything the compiler rewrites on purpose must be mirrored here, and nothing else; every whitelist addition needs review):

  • defaults made explicit: name, channel reducer, retry_policy fields, schema_version dropped when 0/absent
  • inline conditional edges (legacy edges items carrying condition / type:"conditional") are moved into conditional_edges
  • owned arrays sorted: edges, conditional_edges, interrupt_before/after (deduped), barrier wait_for (deduped)
  • empty owned containers dropped (routes:{}, interrupt:[])
  • _/x- annotation keys stripped at every owned level (node config contents are not descended into)

Unknown keys are deliberately PRESERVED, not stripped — that is how the TV compare flags a key the compiler ignored.

◆ compile() [1/2]

static CompiledGraph neograph::graph::GraphCompiler::compile ( const json &  definition,
const NodeContext &  default_context 
)
static

Parse a JSON graph definition into a CompiledGraph.

Parameters
definitionTop-level graph JSON ({schema_version, name, channels, nodes, edges, conditional_edges, interrupt_before, interrupt_after, retry_policy}).
default_contextShared NodeContext forwarded to every NodeFactory-created node.
Returns
Fully parsed CompiledGraph. Safe to std::move into GraphEngine internals.
Exceptions
std::runtime_errorIf a required field is malformed or a referenced node type is unknown.

Strict mode (consumed-key accounting)

A document declaring "schema_version": 1 opts into strict compilation: every key of every object the compiler owns (top level, channel defs, node defs, barrier, edges, conditional_edges items, retry_policy) must be consumed by the parser. A key nobody consumed — a typo like conditionnal_edges, a field the engine doesn't support, a barrier whose wait_for is missing/empty — is a hard compile error listing every offender. This makes the v0.1.0–v0.1.7 "silently dropped block" regression class structurally impossible: deleting a parsing step deletes its consumption mark, and any document using that feature fails loudly instead of degrading silently. Registered node config schemas additionally enforce NeoGraph's declared required, type, and enum subset before a node factory runs. Diagnostics use stable JSON paths; other JSON Schema keywords remain descriptive unless documented separately.

Annotation namespace: keys starting with _ or x- (e.g. _comment, x-studio-pos) are never consumed, never errors, and are ignored by canon() — they belong to humans and tooling, not to the engine.

Documents without schema_version (or 0) keep the historical lenient behavior byte-for-byte. schema_version above the engine's supported version (currently 1) is always an error.

◆ compile() [2/2]

static CompiledGraph neograph::graph::GraphCompiler::compile ( const json &  definition,
const NodeContext &  default_context,
const GraphRegistry &  registry 
)
static

Compile with a local-first registry overlay.

Missing entries fall back to the process-global registries, preserving built-ins and existing registrations without process-wide mutation. Pass the same registry through EngineResources when linking the result, so runtime reducer and condition lookup uses the same overlay.

◆ upgrade_to_latest()

static json neograph::graph::GraphCompiler::upgrade_to_latest ( const json &  definition)
static

Upgrade a legacy (schema_version 0 / absent) topology document to the current schema version.

v0 → v1 is purely mechanical and lossless: it stamps the current schema_version, moves barrier blocks whose wait_for is missing/empty into the annotation namespace (making the legacy silent drop explicit), and renames every key strict mode would refuse to x-upgraded-<key> — the annotation namespace — so no user data is deleted, it is just moved out of the engine's way exactly as the lenient parser ignored it.

Guarantee (tested over the corpus): compiling the legacy document leniently and compiling the upgraded document strictly yield IR-equivalent graphs (canon(to_json()) equal modulo the schema_version stamp).

Like compile(), node-config upgrading consults NodeFactory — register custom node types before calling. Documents already at the current version are returned unchanged.

◆ verify_roundtrip()

static void neograph::graph::GraphCompiler::verify_roundtrip ( const json &  definition,
const CompiledGraph &  cg 
)
static

Translation validation: assert compile() lost nothing.

Compares canon(definition) against canon(cg.to_json()). On mismatch: throws std::runtime_error carrying the JSON-Patch diff when the document is strict (schema_version >= 1); writes a one-shot warning to stderr when lenient (legacy documents keep compiling, but silent drops become visible).


The documentation for this class was generated from the following file: