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

Result of a graph execution run. More...

#include <engine.h>

Public Member Functions

bool barrier_stalled () const noexcept
 True when the run stopped with nothing ready and end never reached while a barrier still held partial signals.
 
template<typename T >
T channel (const ChannelKey< T > &key) const
 Read a channel using a reusable typed key.
 
template<typename T >
T channel (const std::string &name) const
 Read a channel value as type T (issue #25).
 
json channel_raw (const std::string &name) const
 Read a channel value as a raw json node (issue #25).
 
bool failure_exited () const noexcept
 True when a failure-exit node completed (#364).
 
bool has_channel (const std::string &name) const noexcept
 Test whether a channel value exists in either shape.
 
bool max_steps_exhausted () const noexcept
 True only when execution stopped at RunConfig::max_steps while work remained ready.
 
bool safe_point_reached () const noexcept
 True only when a host-owned request stopped the run at a durable boundary.
 
RunStatus status () const noexcept
 Return a typed outcome without changing the legacy result layout.
 
template<typename T >
std::optional< T > try_channel (const ChannelKey< T > &key) const
 Read a typed channel when present, preserving conversion errors.
 

Public Attributes

std::string checkpoint_id
 ID of the last checkpoint saved.
 
std::vector< std::string > execution_trace
 One entry per node execution that completed, in the order the engine applied the results.
 
std::string interrupt_id
 #388: the id of the NodeInterrupt this result reports (interrupt_node, interrupt_value): the first pending interrupt of the paused step, and the one a resume answers unless it names another.
 
std::string interrupt_node
 Name of the node that triggered the interrupt.
 
json interrupt_value
 Value associated with the interrupt.
 
bool interrupted = false
 True if execution was interrupted (HITL).
 
std::vector< PendingInterrupt > interrupts
 #388: every NodeInterrupt of the paused step, in ready order and then Send order; the first is the one this result reports.
 
json output
 Final serialized graph state. See struct docstring for shape details.
 
sp::Usage usage
 Token usage for the whole run, subgraphs included (issue #88).
 

Detailed Description

Result of a graph execution run.

<tt>output</tt> shape (issue #25)

The canonical shape of output is channels-wrapped: each channel value lives at output["channels"][<name>]["value"], with sibling metadata such as ["version"].

<tt>version</tt> and <tt>global_version</tt>

A run has one write counter, shared by all its channels, that starts at 0. Every channel write adds 1 to it and stamps the written channel with the new value: the writes of the run input (one per input key that names a declared channel), of the nodes and of a Command's updates all count, and a write that leaves the value unchanged counts too. output["channels"][<name>]["version"] is the counter's value at that channel's last write, and output["global_version"] is its value after the run's last write. So versions rise with every write and no two channels share one, but a version is neither the number of writes the channel received nor a super-step number (Checkpoint::step is the super-step). A channel that was never written has version 0, even when it has an initial value. Checkpoints keep both numbers: a resumed or forked run restores them and goes on counting from there, so the numbers continue across a pause instead of starting over.

Some compiled flows project additional flat top-level keys for ergonomic access — e.g. react_graph exposes a synthetic output["final_response"] so the README quickstart can read the model's last reply with one bracket. These projections coexist with the channels wrapper; the wrapper is always present and is the source of truth.

Use the channel<T>(name) accessor below to read a channel value without committing to either shape — it checks the channels wrapper first, then falls back to a flat top-level key with the same name. That way the same call site works against GraphEngine::build- built graphs (channels-wrapped only) and react_graph-built graphs (channels-wrapped + flat-key projections) alike.

Definition at line 431 of file engine.h.

Member Function Documentation

◆ barrier_stalled()

bool neograph::graph::RunResult::barrier_stalled ( ) const
inlinenoexcept

True when the run stopped with nothing ready and end never reached while a barrier still held partial signals.

The stalled joins are listed at output["_neograph"]["barrier_stalled"] as {node, wait_for, received, missing} objects.

Definition at line 494 of file engine.h.

References output.

Referenced by status().

◆ channel()

template<typename T >
T neograph::graph::RunResult::channel ( const std::string &  name) const
inline

Read a channel value as type T (issue #25).

Looks up the value in output. Tries the canonical channels-wrapped path first (output["channels"][name]["value"]); falls back to a flat top-level key (output[name]) for graphs that project flat keys such as react_graph's final_response.

Exceptions
json::out_of_rangeif no channel with that name exists in either shape.
json::type_errorif the channel exists but its value cannot be converted to T (delegated to json::get<T>).
Template Parameters
TOne of the types json::get<T> is specialised for — int, long, double, std::string, bool, json, etc. See json.h.

Definition at line 536 of file engine.h.

References channel_raw().

Referenced by try_channel().

◆ channel_raw()

json neograph::graph::RunResult::channel_raw ( const std::string &  name) const
inline

Read a channel value as a raw json node (issue #25).

Same lookup rules as channel<T> — channels-wrapped first, flat top-level key as fallback. Returns the underlying json so the caller can walk arrays / objects without committing to a scalar conversion.

Exceptions
json::out_of_rangeif no channel with that name exists in either shape.

Definition at line 562 of file engine.h.

References output.

Referenced by channel().

◆ failure_exited()

bool neograph::graph::RunResult::failure_exited ( ) const
inlinenoexcept

True when a failure-exit node completed (#364).

The node and its declared code are at output["_neograph"]["failure_exit"] as {"node", "code"}; the code is NG.Aborted when the node declares none.

Definition at line 503 of file engine.h.

References output.

Referenced by status().

◆ has_channel()

bool neograph::graph::RunResult::has_channel ( const std::string &  name) const
inlinenoexcept

Test whether a channel value exists in either shape.

True if either the channels-wrapped path or a flat top-level key with the same name resolves. Useful as a guard before channel<T> when the graph may or may not have written the channel (e.g. early HITL interrupt before a node ran).

Definition at line 579 of file engine.h.

References output.

Referenced by try_channel().

◆ max_steps_exhausted()

bool neograph::graph::RunResult::max_steps_exhausted ( ) const
inlinenoexcept

True only when execution stopped at RunConfig::max_steps while work remained ready.

The status is stored in output rather than as a data member so adding this query does not change RunResult's binary layout.

Definition at line 477 of file engine.h.

References output.

Referenced by status().

Member Data Documentation

◆ execution_trace

std::vector<std::string> neograph::graph::RunResult::execution_trace

One entry per node execution that completed, in the order the engine applied the results.

Super-steps come in order; within a step the ready nodes come in ready order, then the Sends in the order they were emitted (the ready nodes' order, then each node's own), whatever order the executions finished in. A Send execution is listed as "<target>[send]". A step that paused lists nothing. A resumed run lists the steps after its checkpoint, the re-entered step whole with its replayed executions. A subgraph is one entry; its inner nodes are not listed.

Definition at line 445 of file engine.h.

◆ interrupt_id

std::string neograph::graph::RunResult::interrupt_id

#388: the id of the NodeInterrupt this result reports (interrupt_node, interrupt_value): the first pending interrupt of the paused step, and the one a resume answers unless it names another.

Empty for an interrupt_before or interrupt_after pause.

Definition at line 468 of file engine.h.

◆ interrupts

std::vector<PendingInterrupt> neograph::graph::RunResult::interrupts

#388: every NodeInterrupt of the paused step, in ready order and then Send order; the first is the one this result reports.

Empty unless the run paused on a NodeInterrupt.

Definition at line 472 of file engine.h.

◆ usage

sp::Usage neograph::graph::RunResult::usage

Token usage for the whole run, subgraphs included (issue #88).

Zero for a graph that made no LLM calls — not an error, just nothing to count.

A graph-managed bank spans checkpoint/resume operations; its actual nullable reports remain cumulative and never include conservative holds. Caller-supplied banks retain the caller's own lifetime/accounting scope.

For cost accounting that survives retries, hand the engine your own accumulator via RunConfig::usage: it outlives the failed attempt because it is yours and the engine only borrows it.

See also
UsageAccounting.ACrashedAttemptIsInvisibleToRunResult
UsageAccounting.ACallerSuppliedAccumulatorSeesTheCrashedAttempt

Definition at line 460 of file engine.h.


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