NeoGraph 0.16.0
A C++20 Graph Agent Engine Library — LangGraph for C++
Loading...
Searching...
No Matches
engine.h
Go to the documentation of this file.
1
9#pragma once
10
11#include <neograph/api.h>
19#include <neograph/graph/node.h>
23#include <neograph/graph/registry.h>
31#include <neograph/tool_dispatch.h> // ToolGate (issue #89)
32#include <neograph/tool_set.h>
33#include <neograph/provider.h>
34
35#include <asio/awaitable.hpp>
36#include <asio/thread_pool.hpp>
37
38#include <atomic>
39#include <chrono>
40#include <cstddef>
41#include <map>
42#include <memory>
43#include <optional>
44#include <set>
45#include <string>
46#include <vector>
47
48namespace neograph {
49class HookRuntime;
50class RuntimeInterpositionController;
51}
52namespace neograph::graph {
53
54class ValidatedTopology;
55namespace detail {
56struct SubgraphWriteJournal;
57struct FailureRouting;
58} // namespace detail
59
61class NEOGRAPH_API ManagedBudgetLeaseReleaseError final : public ProviderOutcomeError {
62public:
63 ManagedBudgetLeaseReleaseError(sp::runtime::Result outcome, std::exception_ptr execution_error,
64 std::exception_ptr release_error)
65 : ProviderOutcomeError("Managed budget lease release failed", std::move(outcome),
66 std::move(execution_error)),
67 release_error_(std::move(release_error)) {}
68 const std::exception_ptr& release_error() const noexcept { return release_error_; }
69private:
70 std::exception_ptr release_error_;
71};
72
88
90 std::shared_ptr<CheckpointStore> checkpoint_store;
91
93 std::shared_ptr<Store> store;
94
96 std::optional<RetryPolicy> retry_policy;
97
103 std::map<std::string, RetryPolicy> node_retry_policies;
104
107
110 std::shared_ptr<ToolExecutionController> tool_execution_controller;
111
115 std::shared_ptr<::neograph::HookRuntime> hook_runtime;
116
118 std::size_t worker_count = 1;
119
124
131 bool stderr_notices = true;
132
137 std::set<std::string> cached_nodes;
138
140 std::size_t node_cache_max_entries = 0;
141
146 std::map<std::string, CacheKeyPolicy> node_cache_policies;
147
149 std::shared_ptr<::neograph::RuntimeInterpositionController> runtime_interposition;
150 std::shared_ptr<sp::NativeArchive> native_history_archive;
151
156};
157
172 ToolSet tools;
173 std::shared_ptr<const GraphRegistry> registry;
174};
175
184 std::shared_ptr<CheckpointStore> checkpoint_store;
185 std::shared_ptr<Store> store;
187 std::optional<ToolGate> tool_gate;
190 std::shared_ptr<ToolExecutionController> tool_execution_controller;
194 std::shared_ptr<ProviderCallBroker> provider_call_broker;
196 std::shared_ptr<ToolEffectBroker> tool_effect_broker;
203 std::shared_ptr<::neograph::HookRuntime> hook_runtime;
204};
205
209 std::string node_name;
210 int parent_step = 0;
211 std::string task_id;
214};
215
216struct NestedCheckpoint {
217 std::vector<std::string> graph_path;
218 std::string thread_id;
219 Checkpoint checkpoint;
220};
221
225struct RunConfig {
226 std::string thread_id;
227 json input;
228 int max_steps = 50;
229 StreamMode stream_mode = StreamMode::ALL;
231 std::optional<std::vector<sp::Message>> provider_messages;
232 std::shared_ptr<sp::NativeArchive> native_history_archive;
233 std::function<void(const sp::Event&)> on_provider_event;
234 std::shared_ptr<ProviderOutcomes> provider_outcomes;
235 std::shared_ptr<ProviderLoopHistory> provider_loop_history;
236
250 std::shared_ptr<CancelToken> cancel_token;
251
256 std::shared_ptr<UsageAccumulator> usage;
257
259 std::uint64_t model_token_budget = 0;
261 std::shared_ptr<std::atomic_bool> budget_exhausted;
262
291 bool resume_if_exists = false;
292
293};
294
308public:
309 explicit NodeRetryCeiling(std::uint64_t limit) noexcept : limit_(limit) {}
310 NodeRetryCeiling(const NodeRetryCeiling&) = delete;
311 NodeRetryCeiling& operator=(const NodeRetryCeiling&) = delete;
312
314 bool try_take() noexcept {
315 auto used = used_.load(std::memory_order_relaxed);
316 while (used < limit_) {
317 if (used_.compare_exchange_weak(used, used + 1, std::memory_order_acq_rel,
318 std::memory_order_relaxed))
319 return true;
320 }
321 return false;
322 }
323 std::uint64_t used() const noexcept { return used_.load(std::memory_order_acquire); }
324 std::uint64_t limit() const noexcept { return limit_; }
325
326private:
327 std::uint64_t limit_;
328 std::atomic<std::uint64_t> used_{0};
329};
330
342 std::optional<std::chrono::steady_clock::time_point> deadline;
343 std::string trace_id;
345 std::string run_id;
347 std::string owner_scope;
349 std::shared_ptr<CancelToken> budget_cancel_token;
354 bool shared_scheduler = false;
360 asio::any_io_executor dispatch_executor;
363 std::shared_ptr<NodeRetryCeiling> node_retry_ceiling;
375};
376
378enum class RunStatus {
379 Completed,
380 Interrupted,
381 StepLimit,
382 SafePoint,
389};
390
431struct RunResult {
432 json output;
433 bool interrupted = false;
434 std::string interrupt_node;
436 std::string checkpoint_id;
445 std::vector<std::string> execution_trace;
446
460 sp::Usage usage;
461 std::vector<sp::Message> native_messages;
462 std::vector<sp::runtime::Result> provider_outcomes;
463
468 std::string interrupt_id;
472 std::vector<PendingInterrupt> interrupts;
473
477 inline bool max_steps_exhausted() const noexcept {
478 if (!output.is_object()) return false;
479 const auto metadata = output["_neograph"];
480 return metadata.is_object() && metadata.value("max_steps_exhausted", false);
481 }
482
484 inline bool safe_point_reached() const noexcept {
485 if (!output.is_object()) return false;
486 const auto metadata = output["_neograph"];
487 return metadata.is_object() && metadata.value("safe_point", false);
488 }
489
494 inline bool barrier_stalled() const noexcept {
495 if (!output.is_object()) return false;
496 const auto metadata = output["_neograph"];
497 return metadata.is_object() && metadata.contains("barrier_stalled");
498 }
499
503 inline bool failure_exited() const noexcept {
504 if (!output.is_object()) return false;
505 const auto metadata = output["_neograph"];
506 return metadata.is_object() && metadata.contains("failure_exit");
507 }
508
510 RunStatus status() const noexcept {
511 if (interrupted) return RunStatus::Interrupted;
512 if (safe_point_reached()) return RunStatus::SafePoint;
513 if (max_steps_exhausted()) return RunStatus::StepLimit;
514 if (failure_exited()) return RunStatus::FailureExit;
515 if (barrier_stalled()) return RunStatus::BarrierStalled;
516 return RunStatus::Completed;
517 }
518
535 template <typename T>
536 T channel(const std::string& name) const {
537 return channel_raw(name).get<T>();
538 }
539
541 template <typename T>
542 T channel(const ChannelKey<T>& key) const {
543 return channel<T>(key.name());
544 }
545
547 template <typename T>
548 std::optional<T> try_channel(const ChannelKey<T>& key) const {
549 if (!has_channel(key.name())) return std::nullopt;
550 return channel(key);
551 }
552
562 json channel_raw(const std::string& name) const {
563 if (output.contains("channels") && output["channels"].contains(name)) {
564 const auto wrapped = output["channels"][name];
565 if (wrapped.contains("value")) return wrapped["value"];
566 }
567 if (output.contains(name)) return output[name];
568 throw json::out_of_range(
569 "RunResult::channel: no such channel '" + name + "' in output "
570 "(checked output[\"channels\"][\"" + name + "\"][\"value\"] and output[\"" + name + "\"])");
571 }
572
579 bool has_channel(const std::string& name) const noexcept {
580 if (output.contains("channels") && output["channels"].contains(name)
581 && output["channels"][name].contains("value")) {
582 return true;
583 }
584 return output.contains(name);
585 }
586};
587
648class NEOGRAPH_API GraphEngine {
649public:
655
656 void set_native_history_archive(std::shared_ptr<sp::NativeArchive> archive) {
657 native_history_archive_ = std::move(archive);
658 }
680 static std::unique_ptr<GraphEngine> link(CompiledGraph graph, EngineConfig config = {});
681
688 static std::unique_ptr<GraphEngine> link(CompiledGraph graph,
689 EngineConfig config,
690 EngineResources resources);
691
693 static std::unique_ptr<GraphEngine> link(
694 CompiledGraph graph,
695 EngineConfig config,
696 EngineResources resources,
697 GraphGenerationIdentity generation);
698
702 static std::unique_ptr<GraphEngine> link(ValidatedTopology topology,
703 EngineConfig config = {});
704
706 static std::unique_ptr<GraphEngine> link(ValidatedTopology topology,
707 EngineConfig config,
708 EngineResources resources);
709
722 static std::unique_ptr<GraphEngine> build(const json& definition, EngineConfig config);
723
730 static std::unique_ptr<GraphEngine> build(const json& definition,
731 EngineConfig config,
732 EngineResources resources);
733
742 static std::unique_ptr<GraphEngine> build_strict(const json& definition,
743 EngineConfig config);
744
746 static std::unique_ptr<GraphEngine> build_strict(const json& definition,
747 EngineConfig config,
748 EngineResources resources);
749
765 static std::unique_ptr<GraphEngine> compile(
766 const json& definition,
767 const NodeContext& default_context,
768 std::shared_ptr<CheckpointStore> store = nullptr);
769
780 RunResult run(const RunConfig& config);
781
784 RunResult run(const RunConfig& config, const RunMetadata& metadata);
785
804 asio::awaitable<RunResult> run_async(RunConfig config);
805
807 asio::awaitable<RunResult> run_async(RunConfig config, RunMetadata metadata);
808
810 asio::awaitable<RunResult> run_async(
811 RunConfig config, RunMetadata metadata, RunResources resources);
812
820 const GraphStreamCallback& cb);
821
824 const GraphStreamCallback& cb,
825 const RunMetadata& metadata);
826
830 asio::awaitable<RunResult> run_stream_async(
831 RunConfig config, GraphStreamCallback cb);
832
834 asio::awaitable<RunResult> run_stream_async(
835 RunConfig config, GraphStreamCallback cb, RunMetadata metadata);
836
838 asio::awaitable<RunResult> run_stream_async(
839 RunConfig config,
841 RunMetadata metadata,
842 RunResources resources);
843
845 asio::awaitable<RunResult> run_until_safe_point_async(
846 RunConfig config,
847 std::shared_ptr<GraphSafePointRequest> request,
848 GraphStreamCallback cb = {},
849 RunMetadata metadata = {},
850 RunResources resources = {});
851
867 RunResult resume(const std::string& thread_id,
868 const json& resume_value = json(),
869 const GraphStreamCallback& cb = nullptr);
870
878 const json& resume_value = json(),
879 const GraphStreamCallback& cb = nullptr);
880
885 const json& resume_value,
886 const GraphStreamCallback& cb,
887 const RunMetadata& metadata);
888
893 asio::awaitable<RunResult> resume_async(
894 const std::string& thread_id,
895 const json& resume_value = json(),
896 const GraphStreamCallback& cb = nullptr);
897
899 asio::awaitable<RunResult> resume_async(RunConfig config,
900 json resume_value = json(),
901 GraphStreamCallback cb = nullptr);
902
904 asio::awaitable<RunResult> resume_async(RunConfig config,
905 json resume_value,
907 RunMetadata metadata);
908
910 asio::awaitable<RunResult> resume_async(RunConfig config,
911 json resume_value,
913 RunMetadata metadata,
914 RunResources resources);
915
916
924 RunConfig config,
925 std::string checkpoint_id,
926 json resume_value = {},
927 GraphStreamCallback cb = {},
928 RunMetadata metadata = {},
929 RunResources resources = {});
930
932 asio::awaitable<RunResult> resume_from_async(
933 RunConfig config,
934 std::string checkpoint_id,
935 json resume_value = {},
936 GraphStreamCallback cb = {},
937 RunMetadata metadata = {},
938 RunResources resources = {});
939
941 asio::awaitable<RunResult> resume_from_until_safe_point_async(
942 RunConfig config,
943 std::string checkpoint_id,
944 std::shared_ptr<GraphSafePointRequest> request,
945 json resume_value = {},
946 GraphStreamCallback cb = {},
947 RunMetadata metadata = {},
948 RunResources resources = {});
949
951 GraphAdmin admin() noexcept;
952
953 // ── State inspection & manipulation (LangGraph Checkpointer API) ──
954
960 std::optional<json> get_state(const std::string& thread_id) const;
961
968 std::vector<Checkpoint> get_state_history(const std::string& thread_id,
969 int limit = 100) const;
970
975 std::optional<NestedCheckpoint> inspect_nested_checkpoint(
976 const std::string& root_thread_id,
977 const std::vector<SubgraphPathStep>& path,
978 std::shared_ptr<CheckpointStore> run_checkpoint_store = {}) const;
979
990 void update_state(const std::string& thread_id,
991 const json& channel_writes,
992 const std::string& as_node = "");
993
1000 void update_state_writes(const std::string& thread_id,
1001 const std::vector<ChannelWrite>& channel_writes,
1002 const std::string& as_node = "");
1003
1024 std::string fork(const std::string& source_thread_id,
1025 const std::string& new_thread_id,
1026 const std::string& checkpoint_id = "");
1027
1028 // ── Configuration ──
1029
1030
1035 void set_checkpoint_store(std::shared_ptr<CheckpointStore> store);
1036
1042 void set_store(std::shared_ptr<Store> store);
1043
1075 void set_tool_gate(ToolGate gate) { tool_gate_ = std::move(gate); }
1076
1080 std::shared_ptr<ToolExecutionController> controller) {
1081 tool_execution_controller_ = std::move(controller);
1082 }
1083
1091 void set_hook_runtime(std::shared_ptr<::neograph::HookRuntime> runtime) {
1092 hook_runtime_ = std::move(runtime);
1093 }
1094
1098 std::shared_ptr<::neograph::RuntimeInterpositionController> controller);
1099
1104 std::shared_ptr<Store> get_store() const { return store_; }
1105
1110 void set_retry_policy(const RetryPolicy& policy);
1111
1128 void set_node_retry_policy(const std::string& node_name, const RetryPolicy& policy);
1129
1132 RetryPolicy resolved_retry_policy(const std::string& node_name) const {
1133 return get_retry_policy(node_name);
1134 }
1135
1158 void set_node_attempt_timeout_ms(const std::string& node_name, std::optional<int> timeout_ms);
1159
1163 std::optional<int> resolved_attempt_timeout_ms(const std::string& node_name) const;
1164
1190 void set_worker_count(std::size_t n);
1191
1204
1230 void set_node_cache_enabled(const std::string& node_name, bool enabled);
1231
1233 void set_node_cache_enabled(const std::string& node_name,
1234 bool enabled,
1235 CacheKeyPolicy policy);
1236
1241
1244 void set_node_cache_max_entries(std::size_t max_entries);
1245
1247 const NodeCache& node_cache() const { return node_cache_; }
1248
1253 const std::string& get_graph_name() const { return name_; }
1254
1255private:
1256 friend class SubgraphNode;
1257
1258 struct SubgraphRunResult {
1259 RunResult result;
1260 std::vector<ChannelWrite> writes;
1261 };
1262
1263 struct RuntimeResources {
1264 std::optional<std::shared_ptr<CheckpointStore>> checkpoint_store;
1265 std::optional<std::shared_ptr<Store>> store;
1266 std::optional<ToolGate> parent_tool_gate;
1267 std::shared_ptr<ToolExecutionController> tool_execution_controller;
1268 std::shared_ptr<ProviderCallBroker> provider_call_broker;
1269 std::shared_ptr<ToolEffectBroker> tool_effect_broker;
1270 ToolEffectGrantIdentity tool_effect_grant;
1271 std::shared_ptr<::neograph::HookRuntime> hook_runtime;
1274 std::shared_ptr<::neograph::HookRuntime> parent_hook_runtime;
1275 std::shared_ptr<detail::SubgraphWriteJournal> subgraph_write_journal;
1276 std::shared_ptr<GraphSafePointRequest> safe_point_request;
1277 };
1278
1279 GraphEngine() = default;
1280 std::shared_ptr<sp::NativeArchive> native_history_archive_;
1281
1282 static std::unique_ptr<GraphEngine> link_impl(CompiledGraph graph,
1283 EngineConfig config,
1284 EngineResources resources,
1285 bool validate);
1286
1289 ToolGate tool_gate_;
1290
1293 std::shared_ptr<ToolExecutionController> tool_execution_controller_;
1294
1297 std::shared_ptr<::neograph::HookRuntime> hook_runtime_;
1298
1301 std::shared_ptr<::neograph::RuntimeInterpositionController> runtime_interposition_;
1302 // Admission state: -1 = exclusive administration; >=0 = active executions.
1303 // No heap allocation or lock on the execution fast path.
1304 void enter_execution();
1305 void leave_execution() noexcept;
1306 void enter_administration() const;
1307 void leave_administration() const noexcept;
1308 struct ExecutionGuard {
1309 explicit ExecutionGuard(GraphEngine& engine);
1310 ExecutionGuard(const ExecutionGuard&) = delete;
1311 ExecutionGuard& operator=(const ExecutionGuard&) = delete;
1312 ~ExecutionGuard();
1313 GraphEngine& engine;
1314 };
1315 struct AdministrationGuard {
1316 explicit AdministrationGuard(const GraphEngine& engine);
1317 AdministrationGuard(const AdministrationGuard&) = delete;
1318 AdministrationGuard& operator=(const AdministrationGuard&) = delete;
1319 ~AdministrationGuard();
1320 const GraphEngine& engine;
1321 };
1322
1323 void init_state(GraphState& state) const;
1324 void apply_input(GraphState& state, const json& input) const;
1325
1326 asio::awaitable<RunResult> resume_execute_async(
1327 RunConfig config,
1328 json resume_value,
1329 GraphStreamCallback cb,
1330 RunMetadata metadata,
1331 RuntimeResources resources,
1332 std::optional<std::string> checkpoint_id);
1333
1334 asio::awaitable<RunResult> run_async_with_runtime(
1335 RunConfig config,
1336 GraphStreamCallback cb,
1337 RunMetadata metadata,
1338 RuntimeResources resources);
1339
1340 asio::awaitable<RunResult> resume_async_with_runtime(
1341 RunConfig config,
1342 json resume_value,
1343 GraphStreamCallback cb,
1344 RunMetadata metadata,
1345 RuntimeResources resources,
1346 std::optional<std::string> checkpoint_id = std::nullopt);
1347
1348 asio::awaitable<SubgraphRunResult> run_subgraph_async(
1349 RunConfig config,
1350 const RunContext& parent,
1351 GraphStreamCallback cb,
1352 SubgraphPersistence persistence);
1353
1359 asio::awaitable<RunResult> execute_graph_async(
1360 const RunConfig& config,
1361 const GraphStreamCallback& cb,
1362 std::optional<ResumeContext> resume_context = std::nullopt,
1363 const json* resume_value = nullptr,
1364 const RunMetadata& metadata = {},
1365 const RuntimeResources* resources = nullptr);
1366
1367 RetryPolicy get_retry_policy(const std::string& node_name) const;
1368 const GraphGenerationIdentity* bound_generation_identity() const noexcept;
1369 std::string managed_budget_graph_identity() const;
1370
1371 // --- Graph definition ---
1372 std::string name_;
1373 std::string budget_graph_identity_;
1374
1377 std::vector<ChannelDef> channel_defs_;
1378
1379 ToolSet tools_;
1381 std::vector<std::unique_ptr<Tool>> owned_tools_;
1382 std::map<std::string, std::unique_ptr<GraphNode>> nodes_;
1384 bool has_stateful_subgraph_ = false;
1385 std::vector<Edge> edges_;
1386 std::vector<ConditionalEdge> conditional_edges_;
1387
1392 std::unique_ptr<Scheduler> scheduler_;
1393
1398 std::unique_ptr<NodeExecutor> executor_;
1399
1400 std::set<std::string> interrupt_before_;
1401 std::set<std::string> interrupt_after_;
1402
1403 std::shared_ptr<CheckpointStore> checkpoint_store_;
1404 std::shared_ptr<Store> store_;
1405
1406 // Retry policies
1407 RetryPolicy default_retry_policy_;
1408 std::map<std::string, RetryPolicy> node_retry_policies_;
1411 std::map<std::string, NodeRetryPolicySpec> sealed_retry_policies_;
1414 std::shared_ptr<const detail::FailureRouting> failure_routing_;
1417 std::map<std::string, int> node_attempt_timeouts_;
1418
1426 std::unique_ptr<asio::thread_pool> pool_;
1427
1430 bool stderr_notices_ = true;
1431
1435 NodeCache node_cache_;
1436 std::atomic<std::uint64_t> next_cache_execution_id_{1};
1437
1443 mutable std::atomic<int> active_runs_{0};
1444
1447 std::shared_ptr<detail::AttemptQuiescence> attempt_quiescence_;
1448};
1449
1450} // namespace neograph::graph
Borrowed state-administration facade for GraphEngine.
NEOGRAPH_API export/import macro for shared-library builds.
Cooperative cancellation primitive for graph runs.
Typed names for JSON-backed graph state channels.
Checkpoint system for graph execution state persistence and time-travel.
Post-dispatch host failure retaining the exact drained provider outcome.
Definition provider.h:204
Copyable owner of a fixed collection of tools.
Definition tool_set.h:21
Bind a channel name to its expected C++ value type.
Definition channel_key.h:19
Abstract interface for checkpoint persistence backends.
Definition checkpoint.h:400
State inspection and mutation separated from graph execution calls.
Definition admin.h:31
Super-step loop execution engine for graph-based agent workflows.
Definition engine.h:648
void set_hook_runtime(std::shared_ptr<::neograph::HookRuntime > runtime)
Set the host-owned lifecycle runtime: checkpoint publication, and the BeforeToolExecution/AfterToolEx...
Definition engine.h:1091
asio::awaitable< RunResult > resume_async(RunConfig config, json resume_value, GraphStreamCallback cb, RunMetadata metadata)
Async resume peer with caller-supplied execution metadata.
static std::unique_ptr< GraphEngine > build_strict(const json &definition, EngineConfig config, EngineResources resources)
Strict build overload with owned tools and a local registry.
RunResult run_stream(const RunConfig &config, const GraphStreamCallback &cb, const RunMetadata &metadata)
Streaming execution with optional C++ deadline and trace metadata.
void set_node_retry_policy(const std::string &node_name, const RetryPolicy &policy)
Set a retry policy for a specific node (overrides default).
std::string fork(const std::string &source_thread_id, const std::string &new_thread_id, const std::string &checkpoint_id="")
Fork a thread, creating a new thread from an existing checkpoint.
void set_tool_execution_controller(std::shared_ptr< ToolExecutionController > controller)
Set the shared host resource-admission boundary for tools.
Definition engine.h:1079
RunResult resume_from(RunConfig config, std::string checkpoint_id, json resume_value={}, GraphStreamCallback cb={}, RunMetadata metadata={}, RunResources resources={})
Resume from one exact checkpoint ID.
static std::unique_ptr< GraphEngine > link(ValidatedTopology topology, EngineConfig config, EngineResources resources)
Validated topology link with owned resources and local registry.
RunResult run_stream(const RunConfig &config, const GraphStreamCallback &cb)
Execute the graph with streaming event callbacks.
static std::unique_ptr< GraphEngine > build(const json &definition, EngineConfig config)
Build a ready-to-run engine from one construction-time config.
asio::awaitable< RunResult > resume_from_until_safe_point_async(RunConfig config, std::string checkpoint_id, std::shared_ptr< GraphSafePointRequest > request, json resume_value={}, GraphStreamCallback cb={}, RunMetadata metadata={}, RunResources resources={})
Exact resume peer that may stop at the next requested safe point.
const std::string & get_graph_name() const
Get the graph name (from the JSON definition).
Definition engine.h:1253
static std::unique_ptr< GraphEngine > build(const json &definition, EngineConfig config, EngineResources resources)
Build with owned tools and a local-first registry.
const NodeCache & node_cache() const
Borrow the engine's NodeCache for stats inspection.
Definition engine.h:1247
GraphAdmin admin() noexcept
Borrow the state-administration facade for this engine.
static std::unique_ptr< GraphEngine > build_strict(const json &definition, EngineConfig config)
Build using strict topology validation when schema_version is missing or zero.
static std::unique_ptr< GraphEngine > link(CompiledGraph graph, EngineConfig config, EngineResources resources)
Link with owned tools and a per-engine registry overlay.
void clear_node_cache()
Drop all cached entries (per-node enable state preserved).
void set_runtime_interposition(std::shared_ptr<::neograph::RuntimeInterpositionController > controller)
Opt into controlled LLM dispatch for built-in LLMCallNode instances.
~GraphEngine()
A node attempt that ignored its cancellation past its stop deadline (#364) can outlive its run and th...
void set_store(std::shared_ptr< Store > store)
Set the cross-thread shared memory store.
asio::awaitable< RunResult > run_stream_async(RunConfig config, GraphStreamCallback cb, RunMetadata metadata)
Async streaming peer that preserves the supplied C++ run metadata.
void set_checkpoint_store(std::shared_ptr< CheckpointStore > store)
Set the checkpoint persistence store.
void set_worker_count(std::size_t n)
Resize (or install) the engine-owned worker pool for parallel fan-out.
static std::unique_ptr< GraphEngine > link(CompiledGraph graph, EngineConfig config={})
Link an already compiled graph into a configured runtime.
RunResult resume(const std::string &thread_id, const json &resume_value=json(), const GraphStreamCallback &cb=nullptr)
Resume execution from a HITL interrupt.
void set_tool_gate(ToolGate gate)
Intercept every tool call before it runs (issue #89).
Definition engine.h:1075
RetryPolicy resolved_retry_policy(const std::string &node_name) const
The retry timing node_name runs with after the per-field resolution described at set_node_retry_polic...
Definition engine.h:1132
RunResult run(const RunConfig &config)
Execute the graph synchronously (blocking).
void update_state(const std::string &thread_id, const json &channel_writes, const std::string &as_node="")
Update the state for a thread by applying channel writes.
RunResult resume(const RunConfig &config, const json &resume_value=json(), const GraphStreamCallback &cb=nullptr)
Resume while preserving caller cancellation settings.
static std::unique_ptr< GraphEngine > link(CompiledGraph graph, EngineConfig config, EngineResources resources, GraphGenerationIdentity generation)
Link an engine permanently bound to one exact host generation.
asio::awaitable< RunResult > resume_from_async(RunConfig config, std::string checkpoint_id, json resume_value={}, GraphStreamCallback cb={}, RunMetadata metadata={}, RunResources resources={})
Async exact-checkpoint resume. Every argument is owned by its coroutine.
static std::unique_ptr< GraphEngine > link(ValidatedTopology topology, EngineConfig config={})
Instantiate and link a topology already proven semantically valid.
asio::awaitable< RunResult > run_async(RunConfig config)
Async peer of run() — returns an awaitable yielding the result.
void set_retry_policy(const RetryPolicy &policy)
Set the default retry policy for all nodes.
static std::unique_ptr< GraphEngine > compile(const json &definition, const NodeContext &default_context, std::shared_ptr< CheckpointStore > store=nullptr)
Compile a graph from a JSON definition.
void set_node_attempt_timeout_ms(const std::string &node_name, std::optional< int > timeout_ms)
Set or clear a host attempt timeout for one node (#364).
void set_node_cache_max_entries(std::size_t max_entries)
Set the global NodeCache entry bound.
void set_node_cache_enabled(const std::string &node_name, bool enabled, CacheKeyPolicy policy)
Enable or disable caching with an explicit identity policy.
asio::awaitable< RunResult > run_stream_async(RunConfig config, GraphStreamCallback cb)
Async peer of run_stream — non-blocking coroutine surface.
asio::awaitable< RunResult > resume_async(const std::string &thread_id, const json &resume_value=json(), const GraphStreamCallback &cb=nullptr)
Async peer of resume — non-blocking coroutine surface.
asio::awaitable< RunResult > run_stream_async(RunConfig config, GraphStreamCallback cb, RunMetadata metadata, RunResources resources)
Async streaming peer with per-operation persistence overrides.
void update_state_writes(const std::string &thread_id, const std::vector< ChannelWrite > &channel_writes, const std::string &as_node="")
Update state with ordered writes that preserve ChannelWrite modes.
void set_worker_count_auto()
Opt into a hardware_concurrency()-sized worker pool.
asio::awaitable< RunResult > run_async(RunConfig config, RunMetadata metadata, RunResources resources)
Async non-streaming run with invocation-scoped persistence and provider policy.
std::optional< int > resolved_attempt_timeout_ms(const std::string &node_name) const
The attempt timeout node_name runs with, in milliseconds, after the resolution described at set_node_...
asio::awaitable< RunResult > resume_async(RunConfig config, json resume_value=json(), GraphStreamCallback cb=nullptr)
Async peer of the RunConfig-preserving resume overload.
asio::awaitable< RunResult > run_until_safe_point_async(RunConfig config, std::shared_ptr< GraphSafePointRequest > request, GraphStreamCallback cb={}, RunMetadata metadata={}, RunResources resources={})
Execute normally until a one-shot host request captures a safe point.
RunResult resume(const RunConfig &config, const json &resume_value, const GraphStreamCallback &cb, const RunMetadata &metadata)
Resume with metadata for this new execution attempt.
asio::awaitable< RunResult > resume_async(RunConfig config, json resume_value, GraphStreamCallback cb, RunMetadata metadata, RunResources resources)
Async resume peer with metadata and invocation-scoped resources.
asio::awaitable< RunResult > run_async(RunConfig config, RunMetadata metadata)
Async peer that preserves the supplied C++ run metadata.
RunResult run(const RunConfig &config, const RunMetadata &metadata)
Execute with optional C++ deadline and trace metadata.
void set_node_cache_enabled(const std::string &node_name, bool enabled)
Enable or disable per-node result caching.
std::shared_ptr< Store > get_store() const
Get the cross-thread shared memory store.
Definition engine.h:1104
Both execution evidence and the failed durable disposition remain visible.
Definition engine.h:61
Per-node result cache.
Definition node_cache.h:75
A run-level ceiling on node retries (#364).
Definition engine.h:307
bool try_take() noexcept
Take one retry. False, and nothing taken, when the ceiling is reached.
Definition engine.h:314
Node that runs a compiled GraphEngine as a single node (hierarchical composition).
Definition node.h:343
Topology proven free of static semantic errors.
Definition validator.h:65
CheckpointCoordinator — owns the super-step checkpoint lifecycle.
RunStatus
Normal, paused, or step-limited outcome of a successful run call.
Definition engine.h:378
@ BarrierStalled
Nothing was ready, end was never reached, and a barrier still held partial signals: the join can no l...
NodeExecutor — owns per-super-step node invocation.
JSON → declarative topology parsing and runtime node linking.
Cross-thread shared memory store (LangGraph Store equivalent).
Graph engine type definitions: channels, edges, nodes, events, and control flow.
std::function< void(const GraphEvent &)> GraphStreamCallback
Callback for receiving graph execution events.
Definition types.h:881
std::function< std::string(const NodeFailure &failure)> FailureTextRedactor
Decides the free text a failure record may carry (#364).
Definition types.h:592
StreamMode
Bitfield flags for selecting which events to stream during execution.
Definition types.h:690
Graph node implementations: base class and built-in node types.
Per-node result cache (opt-in).
Host-owned, invocation-scoped boundary for built-in Core provider calls.
Per-run metadata exposed to graph nodes.
Host-owned capture of one durably completed graph super-step.
Pure routing / next-step-planning logic extracted from GraphEngine.
Thread-safe mutable graph state management.
Exact host authorization for one invocation of mediated Tool dispatch.
Explicit cache identity policy for one node.
Definition node_cache.h:45
Serialized snapshot of graph execution state at a single super-step.
Definition checkpoint.h:173
Parsed graph definition, ready for the engine to run.
Definition compiler.h:185
Construction-time configuration for a GraphEngine.
Definition engine.h:85
std::map< std::string, RetryPolicy > node_retry_policies
Per-node retry overrides applied before the first run.
Definition engine.h:103
std::size_t worker_count
Fan-out worker count. One preserves the historical no-pool fast path.
Definition engine.h:118
std::map< std::string, CacheKeyPolicy > node_cache_policies
Explicit per-node cache policy.
Definition engine.h:146
std::optional< RetryPolicy > retry_policy
Optional override for the topology's default retry policy.
Definition engine.h:96
std::shared_ptr<::neograph::HookRuntime > hook_runtime
Optional host-owned lifecycle runtime retained across every run and resume: checkpoint Hooks,...
Definition engine.h:115
ValidationOptions validation
Rules build() and link() validate the topology with.
Definition engine.h:123
bool stderr_notices
Print engine notices to stderr: validation lint from build() and link(), and the one-time "fan-out is...
Definition engine.h:131
FailureTextRedactor failure_text_redactor
#364: the free text a failure record may carry, for nodes whose retry policy opts in with error_text:...
Definition engine.h:155
NodeContext node_context
Provider, tools, model, and instructions used while factories create nodes.
Definition engine.h:87
std::set< std::string > cached_nodes
Pure, context-independent nodes whose results may be reused across executions.
Definition engine.h:137
std::shared_ptr< Store > store
Optional cross-thread long-term memory exposed as RunContext::store.
Definition engine.h:93
std::shared_ptr<::neograph::RuntimeInterpositionController > runtime_interposition
Controlled provider dispatch for built-in LLMCallNode instances.
Definition engine.h:149
std::shared_ptr< CheckpointStore > checkpoint_store
Optional durable execution-state backend.
Definition engine.h:90
ToolGate tool_gate
Engine-wide tool policy, preserved across run() and resume().
Definition engine.h:106
std::size_t node_cache_max_entries
Global NodeCache entry bound. Zero preserves unbounded behavior.
Definition engine.h:140
std::shared_ptr< ToolExecutionController > tool_execution_controller
Shared host admission boundary for every tool call made by this engine.
Definition engine.h:110
Owned construction resources layered beside EngineConfig.
Definition engine.h:171
#364: a node whose completion ends the run as failed.
Definition compiler.h:114
Exact host-supplied identity permanently bound to one linked engine.
Definition safe_point.h:20
Dependency injection context passed to nodes during construction.
Definition types.h:753
Retry policy for node execution with exponential backoff.
Definition types.h:668
Configuration for a graph execution run.
Definition engine.h:225
int max_steps
Safety limit for maximum super-steps per run.
Definition engine.h:228
StreamMode stream_mode
Which event types to emit during streaming.
Definition engine.h:229
std::string thread_id
Thread ID for checkpoint association.
Definition engine.h:226
std::shared_ptr< std::atomic_bool > budget_exhausted
Set by a node that crossed model_token_budget so the enclosing runtime can classify it.
Definition engine.h:261
bool resume_if_exists
Auto-resume from latest checkpoint for thread_id (v0.3.1+).
Definition engine.h:291
json input
Initial channel writes (e.g., {"messages": [...]}).
Definition engine.h:227
std::shared_ptr< UsageAccumulator > usage
Token accounting for this run (issue #88).
Definition engine.h:256
std::shared_ptr< CancelToken > cancel_token
Optional cooperative cancel handle (v0.3+).
Definition engine.h:250
std::optional< std::vector< sp::Message > > provider_messages
Full history input; when set, replaces only the messages channel.
Definition engine.h:231
std::uint64_t model_token_budget
Optional hard model-token ceiling enforced by budget-aware nodes.
Definition engine.h:259
Optional per-run metadata without changing the stable RunConfig ABI.
Definition engine.h:341
bool shared_scheduler
The host runs this graph on a scheduler it shares with other runs and its own timers (the Program run...
Definition engine.h:354
std::shared_ptr< CancelToken > budget_cancel_token
Shared sibling-cancellation scope for budget-aware nodes.
Definition engine.h:349
std::string run_id
Durable Program run identity copied into RunContext for host journaling.
Definition engine.h:345
asio::any_io_executor dispatch_executor
#557: the executor a node attempt that needs its own worker runs on, on a strand of it (shared_schedu...
Definition engine.h:360
std::shared_ptr< NodeRetryCeiling > node_retry_ceiling
#364: the run-level retry ceiling; null means none.
Definition engine.h:363
std::string resume_interrupt_id
#388: on a resume from a NodeInterrupt checkpoint, the interrupt this resume answers: a PendingInterr...
Definition engine.h:374
std::string owner_scope
Stable owner/tenant scope copied into ToolExecutionContext identity.
Definition engine.h:347
Optional persistence resources scoped to one run or resume call.
Definition engine.h:183
std::shared_ptr< ToolEffectBroker > tool_effect_broker
Host broker for mediated Tool effects in this invocation and subgraphs.
Definition engine.h:196
std::shared_ptr< ToolExecutionController > tool_execution_controller
Optional invocation-scoped execution policy, including resume calls.
Definition engine.h:190
ToolEffectGrantIdentity tool_effect_grant
Exact grant identity attached to this invocation's mediated Tool calls.
Definition engine.h:198
std::optional< ToolGate > tool_gate
Optional invocation-scoped gate composed before the engine gate.
Definition engine.h:187
std::shared_ptr< ProviderCallBroker > provider_call_broker
Host broker for built-in provider calls in this invocation and subgraphs.
Definition engine.h:194
std::shared_ptr<::neograph::HookRuntime > hook_runtime
Optional lifecycle runtime for the tool Hooks of this invocation and its subgraphs.
Definition engine.h:203
Result of a graph execution run.
Definition engine.h:431
T channel(const ChannelKey< T > &key) const
Read a channel using a reusable typed key.
Definition engine.h:542
bool max_steps_exhausted() const noexcept
True only when execution stopped at RunConfig::max_steps while work remained ready.
Definition engine.h:477
std::string interrupt_node
Name of the node that triggered the interrupt.
Definition engine.h:434
json channel_raw(const std::string &name) const
Read a channel value as a raw json node (issue #25).
Definition engine.h:562
std::optional< T > try_channel(const ChannelKey< T > &key) const
Read a typed channel when present, preserving conversion errors.
Definition engine.h:548
bool interrupted
True if execution was interrupted (HITL).
Definition engine.h:433
std::vector< PendingInterrupt > interrupts
#388: every NodeInterrupt of the paused step, in ready order and then Send order; the first is the on...
Definition engine.h:472
sp::Usage usage
Token usage for the whole run, subgraphs included (issue #88).
Definition engine.h:460
RunStatus status() const noexcept
Return a typed outcome without changing the legacy result layout.
Definition engine.h:510
std::string interrupt_id
#388: the id of the NodeInterrupt this result reports (interrupt_node, interrupt_value): the first pe...
Definition engine.h:468
bool safe_point_reached() const noexcept
True only when a host-owned request stopped the run at a durable boundary.
Definition engine.h:484
bool has_channel(const std::string &name) const noexcept
Test whether a channel value exists in either shape.
Definition engine.h:579
bool failure_exited() const noexcept
True when a failure-exit node completed (#364).
Definition engine.h:503
std::string checkpoint_id
ID of the last checkpoint saved.
Definition engine.h:436
json interrupt_value
Value associated with the interrupt.
Definition engine.h:435
json output
Final serialized graph state. See struct docstring for shape details.
Definition engine.h:432
bool barrier_stalled() const noexcept
True when the run stopped with nothing ready and end never reached while a barrier still held partial...
Definition engine.h:494
std::vector< std::string > execution_trace
One entry per node execution that completed, in the order the engine applied the results.
Definition engine.h:445
T channel(const std::string &name) const
Read a channel value as type T (issue #25).
Definition engine.h:536
One edge in a nested checkpoint lookup.
Definition engine.h:208
std::string parent_checkpoint_id
Pin a historical parent checkpoint rather than its latest checkpoint.
Definition engine.h:213
Rule selection for GraphValidator.
Definition validator.h:84
The single implementation of "execute an assistant message's tool_calls".
std::function< asio::awaitable< ToolDecision >(ToolCall, ToolGateContext)> ToolGate
Called once per tool call, before any tool runs.
Host-owned replay boundary for one mediated Tool effect.
Static semantic analysis over declarative or compiled topology.