NeoGraph 0.16.0
A C++20 Graph Agent Engine Library — LangGraph for C++
Loading...
Searching...
No Matches
hook.h
Go to the documentation of this file.
1
5#pragma once
6
7#include <neograph/api.h>
8#include <neograph/tool.h>
9
10#include <asio/awaitable.hpp>
11
12#include <cstdint>
13#include <functional>
14#include <memory>
15#include <optional>
16#include <set>
17#include <string>
18#include <string_view>
19#include <vector>
20
21namespace neograph {
22
23// This is deliberately closed: a new phase changes the hook contract.
24enum class HookPhase : std::uint8_t {
25 MessageAdmitted,
26 BeforeProviderRequest,
27 AfterProviderResponse,
28 BeforeToolExecution,
29 AfterToolExecution,
30 CheckpointPublished,
31 BeforeTerminalPublication,
32 RunFailed,
33 RunCancelled,
34};
35NEOGRAPH_API std::string_view to_string(HookPhase value) noexcept;
36NEOGRAPH_API HookPhase hook_phase_from_string(std::string_view value);
37
38enum class HookDelivery : std::uint8_t { BlockingMandatory, DurableObservational };
39enum class HookFailureMode : std::uint8_t { FailClosed, Continue };
40enum class HookIdempotency : std::uint8_t { Idempotent, NonIdempotent };
41
44 std::string event_id;
45 std::uint64_t sequence = 0;
46 HookPhase phase = HookPhase::MessageAdmitted;
47 std::string type;
48 std::string owner_scope;
49 std::string run_id;
50 json data;
51};
52
53class NEOGRAPH_API RuntimeEvent final {
54public:
55 static constexpr std::uint32_t SCHEMA_VERSION = 1;
56 static RuntimeEvent create(RuntimeEventData data);
57 static RuntimeEvent parse(std::string_view stored_bytes);
58
59 [[nodiscard]] const std::string& id() const noexcept { return data_.event_id; }
60 [[nodiscard]] std::uint64_t sequence() const noexcept { return data_.sequence; }
61 [[nodiscard]] HookPhase phase() const noexcept { return data_.phase; }
62 [[nodiscard]] const std::string& type() const noexcept { return data_.type; }
63 [[nodiscard]] const std::string& owner_scope() const noexcept { return data_.owner_scope; }
64 [[nodiscard]] const std::string& run_id() const noexcept { return data_.run_id; }
65 [[nodiscard]] const json& data() const noexcept { return data_.data; }
66 [[nodiscard]] std::string serialize_canonical() const;
67
68private:
69 explicit RuntimeEvent(RuntimeEventData data) : data_(std::move(data)) {}
70 RuntimeEventData data_;
71};
72
73enum class HookPredicateKind : std::uint8_t { True, All, Any, Not, Equals, Exists };
74enum class RuntimeEventField : std::uint8_t { Type, OwnerScope, RunId, DataPointer };
75
78 HookPredicateKind kind = HookPredicateKind::True;
79 RuntimeEventField field = RuntimeEventField::Type;
80 std::string pointer;
81 json value;
82 std::vector<HookPredicate> children;
83};
84
85enum class HookInputMapperKind : std::uint8_t { JsonPointer, Template, HostMapper };
88 HookInputMapperKind kind = HookInputMapperKind::JsonPointer;
89 std::string json_pointer;
90 json value_template;
91 std::string host_mapper_id;
92};
93
94struct HookDefinitionData {
95 std::string definition_id;
96 std::uint32_t priority = 0;
97 HookPhase phase = HookPhase::MessageAdmitted;
98 HookDelivery delivery = HookDelivery::BlockingMandatory;
99 HookFailureMode failure_mode = HookFailureMode::FailClosed;
100 HookIdempotency idempotency = HookIdempotency::Idempotent;
101 ToolEffectClass effect = ToolEffectClass::ReadOnly;
102 std::string target_id;
103 std::set<std::string> required_capabilities;
104 HookPredicate predicate;
105 HookInputMapper input_mapper;
106};
107
108class NEOGRAPH_API HookDefinition final {
109public:
110 static constexpr std::uint32_t SCHEMA_VERSION = 1;
111 static HookDefinition create(HookDefinitionData data);
112 static HookDefinition parse(std::string_view stored_bytes);
113 [[nodiscard]] const std::string& id() const noexcept { return data_.definition_id; }
114 [[nodiscard]] const HookDefinitionData& data() const noexcept { return data_; }
115 [[nodiscard]] std::string serialize_canonical() const;
116
117private:
118 explicit HookDefinition(HookDefinitionData data) : data_(std::move(data)) {}
119 HookDefinitionData data_;
120};
121
122struct HookInvocationData {
123 std::string invocation_id;
124 std::string definition_id;
125 std::string event_id;
126 std::string target_id;
127 HookPhase phase = HookPhase::MessageAdmitted;
128 HookDelivery delivery = HookDelivery::BlockingMandatory;
129 HookFailureMode failure_mode = HookFailureMode::FailClosed;
130 HookIdempotency idempotency = HookIdempotency::Idempotent;
131 ToolEffectClass effect = ToolEffectClass::ReadOnly;
132 std::set<std::string> required_capabilities;
133 std::string host_mapper_id;
134 json arguments;
135};
136
137class NEOGRAPH_API HookInvocation final {
138public:
139 static constexpr std::uint32_t SCHEMA_VERSION = 1;
140 static HookInvocation create(HookInvocationData data);
141 static HookInvocation parse(std::string_view stored_bytes);
142 [[nodiscard]] const std::string& id() const noexcept { return data_.invocation_id; }
143 [[nodiscard]] const HookInvocationData& data() const noexcept { return data_; }
144 [[nodiscard]] std::string serialize_canonical() const;
145
146private:
147 explicit HookInvocation(HookInvocationData data) : data_(std::move(data)) {}
148 HookInvocationData data_;
149};
150
153 Tool* tool = nullptr;
154 std::set<std::string> capabilities;
155 ToolEffectClass maximum_effect = ToolEffectClass::Unknown;
156};
157using HookTargetResolver = std::function<std::optional<HookTargetContract>(std::string_view)>;
158using HookHostMapper = std::function<json(std::string_view, const RuntimeEvent&)>;
159
160class NEOGRAPH_API HookRegistry final {
161public:
162 HookRegistry(HookTargetResolver target_resolver,
163 std::set<std::string> admitted_host_mapper_ids = {});
164 void admit(HookDefinition definition);
165 [[nodiscard]] std::vector<HookInvocation> plan(const RuntimeEvent& event) const;
166
167private:
168 HookTargetResolver target_resolver_;
169 std::set<std::string> admitted_host_mapper_ids_;
170 std::vector<HookDefinition> definitions_;
171};
172
175class NEOGRAPH_API NativeHookExecutionAdapter final {
176public:
177 NativeHookExecutionAdapter(HookTargetResolver target_resolver,
178 std::shared_ptr<ToolExecutionController> controller,
179 HookHostMapper host_mapper = {},
180 std::set<std::string> admitted_host_mapper_ids = {});
181 asio::awaitable<ToolExecutionResult> execute_result_async(
182 const HookInvocation& invocation, const RuntimeEvent& event,
183 ToolExecutionContext context = {}) const;
184
185private:
186 HookTargetResolver target_resolver_;
187 std::shared_ptr<ToolExecutionController> controller_;
188 HookHostMapper host_mapper_;
189 std::set<std::string> admitted_host_mapper_ids_;
190};
191
192} // namespace neograph
NEOGRAPH_API export/import macro for shared-library builds.
Native-only execution bridge.
Definition hook.h:175
Abstract base class for tools that agents can call.
Definition tool.h:114
Template leaves are literals or {"$event":"/data/..."}; no expressions are evaluated.
Definition hook.h:87
Bounded declarative predicate AST.
Definition hook.h:77
The host's admitted target contract.
Definition hook.h:152
Immutable, typed event input to the deterministic hook planner.
Definition hook.h:43
Per-invocation context for a cooperative asynchronous tool.
Definition tool.h:39
Abstract tool interface for callable functions.
ToolEffectClass
Explicit effect classification used to decide retry and recovery behavior.