15#include <neograph/program/core_tool_grant.h>
16#include <neograph/program/core_provider_call.h>
27#include <asio/any_io_executor.hpp>
28#include <asio/awaitable.hpp>
39namespace neograph::program {
40struct ProgramInvocation {
44 std::shared_ptr<ProgramEventSink> events;
45 std::string requested_run_id;
46 std::string parent_run_id;
47 std::uint32_t child_depth = 0;
49 std::optional<RunInvocation> canonical_request;
55 std::shared_ptr<ProgramEventSink> events;
56 std::string pending_id;
59struct ProgramEffectResolution {
60 std::string pending_id;
61 ProgramEffectReconciliation resolution = ProgramEffectReconciliation::Unknown;
62 std::optional<json> result;
64 std::shared_ptr<ProgramEventSink> events;
69 std::string target_program_version_id;
70 std::string requested_run_id;
71 std::shared_ptr<ProgramEventSink> events;
84 std::string_view owner_scope;
85 std::string_view program_version_id;
86 std::string_view run_id;
87 std::string_view operation_id;
88 std::uint64_t attempt = 0;
89 RunBudget granted_budget;
90 std::uint32_t child_depth = 0;
93using ProgramHostAdmissionResolver =
98 std::string owner_scope;
100 std::vector<ProgramContextPublication> context_publications;
101 std::vector<HookOutboxEntry> hook_outbox_entries;
102 std::vector<HookOutboxEntry> inherited_hook_outbox_entries;
103 std::optional<ProgramRuntimeStateTransferReceipt> transfer_receipt;
116using ProgramChildSynthesisGrantResolver = std::function<std::optional<ProgramChildSynthesisGrant>(
117 std::string_view owner_scope, std::string_view parent_run_id, std::string_view grant_id)>;
119struct ProgramChildQuotaConfig {
121 std::uint64_t max_active_children = 0;
122 std::uint64_t max_pending_spawn_requests = 0;
123 std::uint64_t max_active_children_per_owner = 0;
124 std::uint64_t max_pending_spawn_requests_per_owner = 0;
147 struct RuntimeConfig {
148 std::shared_ptr<ProgramCatalog> catalog;
149 std::shared_ptr<graph::CheckpointStore> checkpoints;
150 std::shared_ptr<graph::Store> state_store;
151 std::shared_ptr<ProgramTransitionStore> transitions;
152 std::size_t scheduler_threads = 1;
153 ProgramChildBindingResolver child_binding_resolver;
158 std::shared_ptr<TaskGraphFragmentStore> task_graph_fragments;
159 TaskGraphExpansionPolicyResolver task_graph_policy_resolver;
165 std::shared_ptr<HostAdmissionController> host_admission;
166 ProgramHostAdmissionResolver host_admission_resolver;
168 ProgramChildQuotaConfig child_quota;
172 std::shared_ptr<HookRuntime> hook_runtime;
176 std::shared_ptr<ProgramSynthesisGateway> child_synthesis_gateway;
177 ProgramChildSynthesisGrantResolver child_synthesis_grant_resolver;
182 std::function<void(ProgramHandle,
ProgramHandoff)> checkpoint_handler;
186 bool recover_existing_child_commands =
false;
189 ProgramCoreToolGrantResolver core_tool_grant_resolver;
191 ProgramCoreToolGrantAwaitableResolver core_tool_grant_awaitable_resolver;
194 ProgramCoreProviderCallResolver core_provider_call_resolver;
197 bool require_core_provider_call_broker =
false;
205 bool core_provider_calls_journaled =
false;
208 std::shared_ptr<sp::NativeArchive> native_history_archive;
219 bool fork_may_resend_provider_calls =
false;
237 asio::any_io_executor executor;
246 ProgramActivation activation;
247 ProgramHandle handle;
250class NEOGRAPH_PROGRAM_API ProgramRuntime {
252 explicit ProgramRuntime(RuntimeConfig config);
253 ProgramRuntime(ProgramRuntime&& other)
noexcept;
254 ProgramRuntime& operator=(ProgramRuntime&& other)
noexcept;
255 ProgramRuntime(
const ProgramRuntime&) =
delete;
256 ProgramRuntime& operator=(
const ProgramRuntime&) =
delete;
272 std::shared_ptr<ProgramEventSink> events = {});
274 ProgramHandle start(RunInvocation invocation, std::shared_ptr<ProgramEventSink> events);
283 ProgramHandle replay_recorded(std::string_view source_run_id,
284 RunInvocation invocation,
285 RecordedBindingSet recorded,
286 std::shared_ptr<ProgramEventSink> events = {});
288 ProgramHandle start(std::string_view owner_scope,
289 const ProgramVersion& version,
290 ProgramInvocation invocation);
297 ProgramHandle start_child(std::string_view owner_scope,
298 const ProgramHandle& parent,
299 const ModuleLinkReceipt& link,
300 const ProgramVersion& version,
301 ProgramInvocation invocation);
306 ProgramSynthesisReservation reserve_synthesis(std::string_view owner_scope,
307 const ProgramHandle& source,
308 ProgramHandoff& handoff,
309 const ProgramSynthesisProposal& proposal,
310 std::string_view expected_lineage_head);
312 ProgramChildSynthesisRecord prepare_child_synthesis(std::string_view owner_scope,
313 const ProgramHandle& parent,
314 const ProgramHandoff& handoff,
315 const ProgramSynthesisProposal& proposal,
316 const ProgramChildSynthesisGrant& grant,
317 std::string binding_name);
320 ProgramChildSynthesisRecord recover_child_synthesis(std::string_view owner_scope,
321 std::string_view parent_run_id,
322 std::string_view proposal_id);
323 ProgramHandle reconnect(std::string_view owner_scope, std::string_view run_id);
329 std::vector<ProgramHandle> recover_children(std::string_view owner_scope,
330 std::string_view parent_run_id);
331 ProgramHandle resume(std::string_view owner_scope,
332 std::string_view run_id,
333 ProgramResume resume);
334 ProgramHandle reconcile(std::string_view owner_scope,
335 std::string_view run_id,
336 ProgramEffectResolution resolution);
350 ProgramHandle fork(ExactProgramCheckpointReference source,
351 RunInvocation invocation,
352 ProgramResume resume,
353 std::shared_ptr<ProgramEventSink> events = {});
354 ProgramHandle fork(std::string_view owner_scope,
355 ExactProgramCheckpointReference source,
356 const ProgramVersion& target,
357 ProgramInvocation invocation,
358 ProgramResume resume);
366 ProgramHandle replace(ExactProgramHandoffReference source,
367 RunInvocation invocation,
368 std::shared_ptr<ProgramEventSink> events = {});
370 ProgramHandle replace(ProgramHandoff&& source,
371 RunInvocation invocation,
372 std::shared_ptr<ProgramEventSink> events = {});
373 ProgramHandle replace(std::string_view owner_scope,
374 ExactProgramHandoffReference source,
375 const ProgramVersion& target,
376 ProgramInvocation invocation);
377 ProgramHandle replace(std::string_view owner_scope,
378 ProgramHandoff&& source,
379 const ProgramVersion& target,
380 ProgramInvocation invocation);
385 ProgramHandle migrate_graph(
const ProgramHandle& source,
386 ProgramGraphMigrationTarget target);
388 asio::awaitable<ProgramResult> run_async(std::string owner_scope,
389 ProgramVersion version,
390 ProgramInvocation invocation);
391 asio::awaitable<ProgramResult> resume_async(std::string owner_scope,
393 ProgramResume resume);
394 ProgramResult run(std::string_view owner_scope,
395 const ProgramVersion& version,
396 ProgramInvocation invocation);
412 asio::awaitable<ProgramHandle> start_async(RunInvocation invocation,
413 std::shared_ptr<ProgramEventSink> events = {});
414 asio::awaitable<ProgramActiveRun> start_active_async(RunInvocation invocation,
415 std::shared_ptr<ProgramEventSink> events = {});
416 asio::awaitable<ProgramHandle> start_async(std::string owner_scope,
417 ProgramVersion version,
418 ProgramInvocation invocation);
419 asio::awaitable<ProgramHandle> replay_recorded_async(std::string source_run_id,
420 RunInvocation invocation,
421 RecordedBindingSet recorded,
422 std::shared_ptr<ProgramEventSink> events = {});
423 asio::awaitable<ProgramHandle> start_child_async(std::string owner_scope,
424 ProgramHandle parent,
425 ModuleLinkReceipt link,
426 ProgramVersion version,
427 ProgramInvocation invocation);
428 asio::awaitable<ProgramSynthesisReservation> reserve_synthesis_async(
429 std::string owner_scope, ProgramHandle source, ProgramHandoff& handoff,
430 ProgramSynthesisProposal proposal, std::string expected_lineage_head);
431 asio::awaitable<ProgramChildSynthesisRecord> prepare_child_synthesis_async(
432 std::string owner_scope, ProgramHandle parent,
const ProgramHandoff& handoff,
433 ProgramSynthesisProposal proposal, ProgramChildSynthesisGrant grant, std::string binding_name);
434 asio::awaitable<ProgramChildSynthesisRecord> recover_child_synthesis_async(
435 std::string owner_scope, std::string parent_run_id, std::string proposal_id);
436 asio::awaitable<ProgramHandle> reconnect_async(std::string owner_scope, std::string run_id);
437 asio::awaitable<std::vector<ProgramHandle>> recover_children_async(std::string owner_scope,
438 std::string parent_run_id);
439 asio::awaitable<ProgramHandle> resume_handle_async(std::string owner_scope,
441 ProgramResume resume);
442 asio::awaitable<ProgramHandle> reconcile_async(std::string owner_scope,
444 ProgramEffectResolution resolution);
445 asio::awaitable<ProgramHandle> fork_async(ExactProgramCheckpointReference source,
446 RunInvocation invocation,
447 ProgramResume resume,
448 std::shared_ptr<ProgramEventSink> events = {});
449 asio::awaitable<ProgramHandle> fork_async(std::string owner_scope,
450 ExactProgramCheckpointReference source,
451 ProgramVersion target,
452 ProgramInvocation invocation,
453 ProgramResume resume);
454 asio::awaitable<ProgramHandle> replace_async(ExactProgramHandoffReference source,
455 RunInvocation invocation,
456 std::shared_ptr<ProgramEventSink> events = {});
457 asio::awaitable<ProgramHandle> replace_async(ProgramHandoff source,
458 RunInvocation invocation,
459 std::shared_ptr<ProgramEventSink> events = {});
460 asio::awaitable<ProgramHandle> replace_async(std::string owner_scope,
461 ExactProgramHandoffReference source,
462 ProgramVersion target,
463 ProgramInvocation invocation);
464 asio::awaitable<ProgramHandle> replace_async(std::string owner_scope,
465 ProgramHandoff source,
466 ProgramVersion target,
467 ProgramInvocation invocation);
468 asio::awaitable<ProgramHandle> migrate_graph_async(ProgramHandle source,
469 ProgramGraphMigrationTarget target);
475 ProgramRuntime(std::shared_ptr<Impl> impl, Borrowed)
noexcept;
476 ProgramRuntime borrowed() const noexcept;
480 asio::awaitable<ProgramHandle> migrate_graph_core(ProgramHandle source, ProgramGraphMigrationTarget target);
481 asio::awaitable<ProgramActiveRun> start_active_core(RunInvocation invocation,
482 std::shared_ptr<ProgramEventSink> events);
483 asio::awaitable<ProgramHandle> start_core(RunInvocation invocation, std::shared_ptr<ProgramEventSink> events);
484 asio::awaitable<ProgramHandle> start_core(std::
string owner_scope, ProgramVersion version,
485 ProgramInvocation invocation);
486 asio::awaitable<ProgramHandle> start_resolved_core(std::
string owner_scope, ProgramVersion version,
487 ProgramInvocation invocation,
bool active_selection = false);
488 asio::awaitable<ProgramHandle> start_child_core(std::
string owner_scope, ProgramHandle parent,
489 ModuleLinkReceipt link, ProgramVersion version,
490 ProgramInvocation invocation);
491 asio::awaitable<ProgramHandle> replay_recorded_core(std::
string source_run_id, RunInvocation invocation,
492 RecordedBindingSet recorded,
493 std::shared_ptr<ProgramEventSink> events);
494 asio::awaitable<ProgramHandle> fork_core(ExactProgramCheckpointReference source, RunInvocation invocation,
495 ProgramResume resume, std::shared_ptr<ProgramEventSink> events);
496 asio::awaitable<ProgramHandle> fork_core(std::
string owner_scope, ExactProgramCheckpointReference source,
497 ProgramVersion target, ProgramInvocation invocation,
498 ProgramResume resume);
499 asio::awaitable<ProgramHandle> replace_core(ExactProgramHandoffReference source, RunInvocation invocation,
500 std::shared_ptr<ProgramEventSink> events);
503 asio::awaitable<ProgramHandle> replace_core(ProgramHandoff* source, RunInvocation invocation,
504 std::shared_ptr<ProgramEventSink> events);
505 asio::awaitable<ProgramHandle> replace_core(std::
string owner_scope, ExactProgramHandoffReference source,
506 ProgramVersion target, ProgramInvocation invocation);
507 asio::awaitable<ProgramHandle> replace_core(std::
string owner_scope, ProgramHandoff* source,
508 ProgramVersion target, ProgramInvocation invocation);
509 asio::awaitable<std::vector<ProgramHandle>> recover_children_core(std::
string owner_scope,
510 std::
string parent_run_id);
511 asio::awaitable<ProgramSynthesisReservation> reserve_synthesis_core(
512 std::
string owner_scope, ProgramHandle source, ProgramHandoff* handoff, ProgramSynthesisProposal proposal,
513 std::
string expected_lineage_head);
514 asio::awaitable<ProgramChildSynthesisRecord> prepare_child_synthesis_core(
515 std::
string owner_scope, ProgramHandle parent, const ProgramHandoff* handoff,
516 ProgramSynthesisProposal proposal, ProgramChildSynthesisGrant grant, std::
string binding_name);
517 asio::awaitable<ProgramChildSynthesisRecord> recover_child_synthesis_core(
518 std::
string owner_scope, std::
string parent_run_id, std::
string proposal_id);
521 asio::awaitable<ProgramHandle> reconnect_core(std::
string owner_scope, std::
string run_id,
522 bool transition_lock_held = false);
523 asio::awaitable<ProgramHandle> resume_core(std::
string owner_scope, std::
string run_id, ProgramResume resume);
524 asio::awaitable<ProgramHandle> reconcile_core(std::
string owner_scope, std::
string run_id,
525 ProgramEffectResolution resolution);
527 std::shared_ptr<Impl> impl_;
528 bool borrowed_ = false;
NEOGRAPH_API export/import macro for shared-library builds.
Typed refusals of a Program call that would block a thread that must not block (#557).
Admission and process-local materialization of immutable Programs.
Checkpoint system for graph execution state persistence and time-travel.
Move-only host lease holding a source generator at an exact durable checkpoint.
Marker for exceptions that are configuration or definition verdicts (#364).
Exact-checkpoint Program fork compatibility values.
Cross-thread shared memory store (LangGraph Store equivalent).
Immutable source capsules for prepared GraphEngine migration.
Shared control handle for one Program attempt.
Host-owned lifecycle hook boundary.
Bounded host-resource admission for Program and external work.
Immutable, owner-scoped Program modules and bounded child composition.
Protocol-neutral durable pending input and effect values.
Transport-neutral, owner-scoped Program invocation contracts.
Protocol-neutral, exact-bound recorded capability replay values.
std::function< void(const ProgramRuntimeRecoveryState &)> ProgramRuntimeRecoveryHandler
Host-owned, idempotent recovery boundary.
One atomic request to hold a vector of local host resources.
Experimental owner-scoped new-run selection.
What ProgramRuntime assumes about RuntimeConfig::executor (#557).
bool host_pumped
A host's event loop runs the executor, one turn at a time, and no thread of the process can wait for ...
std::function< bool()> running_in_this_thread
True when the calling thread is one the executor runs handlers on.
Already-admitted immutable target selected by the host for one live migration.
std::optional< GraphSemanticMigrationAdapter > semantic_adapter
Required whenever the target changes the pinned native Core identity.
Immutable data available when a host scheduler admits one Program attempt.
Exact durable runtime state that must be rebound before recovered work can dispatch.
One owner-scoped Program request.
Deterministic lowering and durable publication contracts for dynamic task DAGs.
Atomic owner-scoped Program transition publication.