NeoGraph 0.16.0
A C++20 Graph Agent Engine Library — LangGraph for C++
Loading...
Searching...
No Matches
module.h
Go to the documentation of this file.
1
5#pragma once
6
11
12#include <asio/awaitable.hpp>
13
14#include <cstdint>
15#include <functional>
16#include <memory>
17#include <optional>
18#include <string>
19#include <string_view>
20#include <vector>
21
22namespace neograph::program {
23
24enum class ModuleLifecycle : std::uint8_t {
25 Active,
26 Deprecated,
27 Quarantined,
28 Revoked,
29};
30
31NEOGRAPH_PROGRAM_API std::string_view to_string(ModuleLifecycle state) noexcept;
32NEOGRAPH_PROGRAM_API ModuleLifecycle module_lifecycle_from_string(std::string_view value);
33
35struct ModulePort {
36 std::string name;
37 ContractRecord contract;
38
39 bool operator==(const ModulePort&) const = default;
40};
41
44 std::string name;
45 std::string program_version_id;
46 std::vector<ModulePort> inputs;
47 std::vector<ModulePort> outputs;
48 std::vector<std::string> required_capabilities;
49 std::vector<std::string> required_effects;
50 BudgetLimits budget;
55 ExecutionGuarantee minimum_execution_guarantee = ExecutionGuarantee::Strict;
56
57 bool operator==(const ChildProgramDescriptor&) const = default;
58};
59
60struct ProgramModuleData {
61 std::string owner_scope;
62 ModuleCoordinate coordinate;
63 std::string attestation_id;
64 ModuleLifecycle lifecycle = ModuleLifecycle::Active;
65 std::vector<ModuleCoordinate> dependencies;
71 std::optional<std::string> pure_javascript_source;
72 std::vector<ChildProgramDescriptor> children;
73 std::vector<std::string> allowed_capabilities;
74 std::vector<std::string> declared_effects;
75};
76
82class NEOGRAPH_PROGRAM_API ProgramModule final {
83public:
84 static constexpr std::uint32_t STORAGE_SCHEMA_VERSION = 1;
85
86 static ProgramModule create(ProgramModuleData data);
87 static ProgramModule parse(std::string_view stored_bytes);
88
89 const std::string& owner_scope() const noexcept;
90 const ModuleCoordinate& coordinate() const noexcept;
91 const std::string& attestation_id() const noexcept;
92 ModuleLifecycle lifecycle() const noexcept;
93 const std::vector<ModuleCoordinate>& dependencies() const noexcept;
94 const std::vector<ChildProgramDescriptor>& children() const noexcept;
95 const std::optional<std::string>& pure_javascript_source() const noexcept;
96 const std::vector<std::string>& allowed_capabilities() const noexcept;
97 const std::vector<std::string>& declared_effects() const noexcept;
98 const std::string& id() const noexcept;
99 std::string serialize_canonical() const;
100
101private:
102 struct Impl;
103 explicit ProgramModule(std::shared_ptr<const Impl> impl);
104 static ProgramModule with_lifecycle(const ProgramModule& module, ModuleLifecycle lifecycle);
105
106 std::shared_ptr<const Impl> impl_;
107 friend class InMemoryModuleStore;
108};
109
112 ModuleCoordinate root;
113 std::vector<ProgramModule> modules;
114 std::vector<DependencyReceipt> receipts;
115
116 std::string dependency_merkle_root() const;
117 std::vector<ImportRef> imports() const;
118 std::vector<ModuleCoordinate> coordinates() const;
119};
120
126class NEOGRAPH_PROGRAM_API VerifiedModuleResolver final {
127public:
128 explicit VerifiedModuleResolver(ModuleResolution resolution);
129
131 VerifiedModuleResolver& operator=(VerifiedModuleResolver&&) noexcept;
133 VerifiedModuleResolver& operator=(const VerifiedModuleResolver&) = delete;
135
136 const ModuleResolution& resolution() const noexcept;
137 std::optional<ModuleCoordinate> resolve(std::string_view source_id) const;
138
139private:
140 struct Impl;
141 std::unique_ptr<Impl> impl_;
142};
143
146 std::string child_name;
147 ProgramBundle bundle;
148 ProgramVersion version;
149};
150
153 ProgramModule parent;
154 ModuleResolution resolution;
155 std::vector<ChildProgramBinding> children;
156};
157
164NEOGRAPH_PROGRAM_API void validate_program_composition(
165 const ProgramBundle& parent_bundle, const ProgramComposition& composition);
166
168NEOGRAPH_PROGRAM_API void validate_module_resolution(const ModuleResolution& resolution);
169
176 std::string owner_scope;
177 std::string parent_module_id;
178 std::string dependency_merkle_root;
179 std::string child_name;
180 std::string child_program_version_id;
181 std::string child_bundle_id;
182 std::string child_input_contract_fingerprint;
183 std::string child_output_contract_fingerprint;
184 std::vector<std::string> granted_capabilities;
185 std::vector<std::string> granted_effects;
186 BudgetLimits budget;
187 ExecutionGuarantee minimum_execution_guarantee = ExecutionGuarantee::Strict;
188};
189
190class NEOGRAPH_PROGRAM_API ModuleLinkReceipt final {
191public:
192 static constexpr std::uint32_t STORAGE_SCHEMA_VERSION = 1;
193
194 static ModuleLinkReceipt create(ModuleLinkReceiptData data);
195 static ModuleLinkReceipt parse(std::string_view stored_bytes);
196
197 const std::string& owner_scope() const noexcept;
198 const std::string& parent_module_id() const noexcept;
199 const std::string& dependency_merkle_root() const noexcept;
200 const std::string& child_name() const noexcept;
201 const std::string& child_program_version_id() const noexcept;
202 const std::string& child_bundle_id() const noexcept;
203 const std::string& child_input_contract_fingerprint() const noexcept;
204 const std::string& child_output_contract_fingerprint() const noexcept;
205 const std::vector<std::string>& granted_capabilities() const noexcept;
206 const std::vector<std::string>& granted_effects() const noexcept;
207 const BudgetLimits& budget() const noexcept;
208 ExecutionGuarantee minimum_execution_guarantee() const noexcept;
209 const std::string& id() const noexcept;
210 std::string serialize_canonical() const;
211
212private:
213 struct Impl;
214 explicit ModuleLinkReceipt(std::shared_ptr<const Impl> impl);
215
216 std::shared_ptr<const Impl> impl_;
217};
218
221 ModuleLinkReceipt receipt;
222 ProgramVersion version;
223};
224
225using ProgramChildBindingResolver = std::function<std::optional<ProgramRuntimeChildBinding>(
226 std::string_view owner_scope,
227 std::string_view parent_program_version_id,
228 std::string_view child_binding_name)>;
229
235NEOGRAPH_PROGRAM_API ModuleLinkReceipt link_module_child(
236 const ModuleResolution& resolution,
237 const ProgramModule& parent,
238 std::string_view child_name,
239 const ProgramBundle& child_bundle,
240 const ProgramVersion& child);
241
247class NEOGRAPH_PROGRAM_API ModuleStore {
248public:
249 virtual ~ModuleStore() = default;
250 [[nodiscard]] virtual asio::awaitable<void> publish(const ProgramModule& module) = 0;
251 [[nodiscard]] virtual asio::awaitable<std::optional<ProgramModule>> get(
252 std::string_view content_identity) const = 0;
254 [[nodiscard]] virtual asio::awaitable<std::optional<ProgramModule>> get(
255 std::string_view owner_scope,
256 std::string_view content_identity) const {
257 if (owner_scope.empty()) co_return std::nullopt;
258 const auto module = co_await get(content_identity);
259 if (!module || module->owner_scope() != owner_scope) co_return std::nullopt;
260 co_return module;
261 }
262 [[nodiscard]] virtual asio::awaitable<void> set_lifecycle(
263 std::string_view content_identity,
264 ModuleLifecycle lifecycle) = 0;
265};
266
271class NEOGRAPH_PROGRAM_API SyncModuleStore : public ModuleStore {
272public:
273 // The synchronous operations. Each has the contract of the awaitable operation of the same name.
274 virtual void publish_sync(const ProgramModule& module) = 0;
275 virtual std::optional<ProgramModule> get_sync(std::string_view content_identity) const = 0;
276 virtual std::optional<ProgramModule> get_sync(
277 std::string_view owner_scope,
278 std::string_view content_identity) const {
279 if (owner_scope.empty()) return std::nullopt;
280 const auto module = get_sync(content_identity);
281 if (!module || module->owner_scope() != owner_scope) return std::nullopt;
282 return module;
283 }
284 virtual void set_lifecycle_sync(std::string_view content_identity, ModuleLifecycle lifecycle) = 0;
285
286 // The awaitable interface, completed by the operations above: at once on the calling thread,
287 // or on a thread of a bounded pool when offloads() is true.
288 [[nodiscard]] asio::awaitable<void> publish(const ProgramModule& module) final;
289 [[nodiscard]] asio::awaitable<std::optional<ProgramModule>> get(std::string_view content_identity) const final;
290 [[nodiscard]] asio::awaitable<std::optional<ProgramModule>> get(
291 std::string_view owner_scope,
292 std::string_view content_identity) const final;
293 [[nodiscard]] asio::awaitable<void> set_lifecycle(
294 std::string_view content_identity,
295 ModuleLifecycle lifecycle) final;
296
298 bool completes_at_once() const noexcept { return !offloads(); }
299
300protected:
302 virtual bool offloads() const noexcept { return false; }
303};
304
309class NEOGRAPH_PROGRAM_API BlockingModuleStore {
310public:
311 BlockingModuleStore(std::shared_ptr<ModuleStore> store, BlockingStorePolicy policy = {});
314
315 const std::shared_ptr<ModuleStore>& store() const noexcept { return store_; }
316
317 void publish(const ProgramModule& module) const;
318 std::optional<ProgramModule> get(std::string_view content_identity) const;
319 std::optional<ProgramModule> get(
320 std::string_view owner_scope,
321 std::string_view content_identity) const;
322 void set_lifecycle(std::string_view content_identity, ModuleLifecycle lifecycle) const;
323
324private:
325 std::shared_ptr<ModuleStore> store_;
326 SyncModuleStore* sync_ = nullptr;
327 BlockingStorePolicy policy_;
328};
329
331class NEOGRAPH_PROGRAM_API InMemoryModuleStore final : public SyncModuleStore {
332public:
335 InMemoryModuleStore& operator=(InMemoryModuleStore&&) noexcept;
337 InMemoryModuleStore& operator=(const InMemoryModuleStore&) = delete;
338 ~InMemoryModuleStore() override;
339
340 void publish_sync(const ProgramModule& module) override;
341 std::optional<ProgramModule> get_sync(std::string_view content_identity) const override;
342 std::optional<ProgramModule> get_sync(std::string_view owner_scope,
343 std::string_view content_identity) const override;
344 void set_lifecycle_sync(std::string_view content_identity, ModuleLifecycle lifecycle) override;
345
346private:
347 struct Impl;
348 std::unique_ptr<Impl> impl_;
349};
350
355class NEOGRAPH_PROGRAM_API ModuleResolver final {
356public:
357 explicit ModuleResolver(std::shared_ptr<const ModuleStore> store);
358
359 ModuleResolution resolve(const ModuleCoordinate& root,
360 const PolicySnapshot& policy) const;
362 asio::awaitable<ModuleResolution> resolve_async(ModuleCoordinate root, PolicySnapshot policy) const;
363
364private:
365 // Only the reads of the store are called, and they are const.
366 std::shared_ptr<const ModuleStore> store_;
367 bool synchronous_ = false;
368};
369
370} // namespace neograph::program
Immutable Program admission and policy snapshots.
ExecutionGuarantee
The lowest recoverability/integrity class reachable through an executable closure.
Definition bundle.h:29
A ModuleStore for a caller that cannot suspend.
Definition module.h:309
BlockingModuleStore(ModuleStore &store, BlockingStorePolicy policy={})
A view of a store that outlives it.
Small durable-boundary-compatible store used by the in-process resolver.
Definition module.h:331
Resolves exact, pinned modules.
Definition module.h:355
asio::awaitable< ModuleResolution > resolve_async(ModuleCoordinate root, PolicySnapshot policy) const
The same resolution, awaiting the module store; the arguments are taken by value.
The store of sealed Program modules, as the catalog uses it (#556).
Definition module.h:247
virtual asio::awaitable< std::optional< ProgramModule > > get(std::string_view owner_scope, std::string_view content_identity) const
Wrong-owner module lookups are indistinguishable from absence.
Definition module.h:254
Immutable module metadata.
Definition module.h:82
Base of a ModuleStore whose backend is synchronous.
Definition module.h:271
virtual bool offloads() const noexcept
True for a backend that blocks for long: each operation then runs on a pool thread.
Definition module.h:302
asio::awaitable< std::optional< ProgramModule > > get(std::string_view owner_scope, std::string_view content_identity) const final
Wrong-owner module lookups are indistinguishable from absence.
bool completes_at_once() const noexcept
True when every awaitable operation completes at once on the calling thread, not on a pool thread.
Definition module.h:298
Immutable allowlist view over a verified ModuleResolution.
Definition module.h:126
Immutable content-addressed coordinates for reusable Program modules.
NEOGRAPH_PROGRAM_API ModuleLinkReceipt link_module_child(const ModuleResolution &resolution, const ProgramModule &parent, std::string_view child_name, const ProgramBundle &child_bundle, const ProgramVersion &child)
Link one child descriptor from a verified module closure to an exact admitted ProgramVersion.
NEOGRAPH_PROGRAM_API void validate_program_composition(const ProgramBundle &parent_bundle, const ProgramComposition &composition)
Validate the whole composed Program before any GraphEngine materialization.
NEOGRAPH_PROGRAM_API void validate_module_resolution(const ModuleResolution &resolution)
Validate a resolver-produced closure, including its pinned graph and receipts.
How a Program store call is awaited, and how a synchronous caller waits for one (#556).
When a Blocking...Store may wait for a store call that does not complete at once.
Definition store_call.h:39
A child version and its immutable bundle, paired before dispatch.
Definition module.h:145
Child authority and budget are a strict attenuation of the parent module.
Definition module.h:43
ExecutionGuarantee minimum_execution_guarantee
Weakest child guarantee the parent explicitly accepts.
Definition module.h:55
Exact module address; the content identity is never selected by a range.
Definition coordinate.h:14
Immutable proof that one child descriptor was linked to one exact admitted Program version.
Definition module.h:175
Typed child port.
Definition module.h:35
Result of resolving one module and its complete pinned dependency closure.
Definition module.h:111
Complete pre-dispatch composition proof for one parent Program.
Definition module.h:152
Runtime-only immutable child binding supplied by an owning resolver.
Definition module.h:220
Immutable stored binding between a Program bundle and admission receipts.