Public entry point and adapter port for Gralkor memory.
Named Lens operations use ingest/1 and replace/1; search/1 reads
registered Destinations and may filter episode writers by Lens.
Ingestion resolves an appending Lens and invokes its ingestion process with a
Lens-bound store. Replacement validates and stores the complete graph for a
replaceable Lens. Lenses and Reflections reference first-class Destinations,
each of which names one graph. Appending Lenses select the ontology for their
writes; Reflection Destination outputs select it for runtime-delivered
artefacts. The runtime-targeted arities resolve names from one consuming
AgentServer's atomic configuration snapshot. reflect/5 admits an invocation
without waiting for production and reports its terminal result through the
supplied callback. With empty selectors, search runs every
accessible registered Destination concurrently and returns episodes from
direct, Lens, and Reflection writers. Destination and Lens names are ORed within
their respective selectors and ANDed across them; Lens filters are
applied to episodes and facts. Each result identifies its Destination.
Direct episodes retain their source without Lens or Reflection authorship;
real Lens and Reflection records retain their named writer. Historical
unmarked and operator-labelled records remain readable without an active
operator Lens. Facts, nodes, and Reflection artefacts are explicit
advanced result types.
Capture uses capture/2 with an owning AgentServer PID and an explicit
Gralkor.Capture route. Direct capture selects a registered Destination;
Lens capture runs distinct selected processes without an implicit direct
write. Positional capture adapters raise migration guidance. The low-level
adapter ports retain recall/4, memory_add/3 or /4, and flush operations.
Logical graph IDs are encoded exactly once as g_ plus the lowercase
hexadecimal encoding of every original byte (sanitize_group_id/1).
The personal Destination resolves to personal/<operator id>; other
registered Destinations resolve to their exact shared names. Retired
operator inputs require an explicit migration and never become shared
private-memory graphs.
flush/1 returns :ok before the buffered turns have landed
(fire-and-forget — appropriate for shutdown paths that cannot block).
flush_and_await/2 returns :ok only after buffered ingestion completes,
for callers that must observe completion before rotating state (for example
session-id rotation in JidoGralkor.ContextRotator).
The concrete adapter is resolved from Application.get_env(:jido_gralkor, :client);
defaults to Gralkor.Client.Native (in-process via Pythonx). Tests swap in
Gralkor.Client.InMemory.
No health_check/0 — the embedded runtime is ready by the time
Application.start/2 returns; runtime failures surface from the next call.
Summary
Types
@type agent_name() :: String.t()
@type group_id() :: String.t()
@type messages() :: [Gralkor.Message.t()]
@type runtime_owner() :: pid()
@type search_result() :: Gralkor.Search.result()
@type session_id() :: String.t()
@type user_name() :: String.t()
Callbacks
@callback build_communities(group_id()) :: {:ok, %{communities: non_neg_integer(), edges: non_neg_integer()}} | {:error, term()}
@callback capture(runtime_owner(), Gralkor.Capture.t()) :: :ok | {:error, term()}
@callback flush(session_id()) :: :ok | {:error, term()}
@callback flush_and_await(session_id(), timeout_ms :: pos_integer()) :: :ok | {:error, :timeout} | {:error, term()}
@callback recall(group_id(), agent_name(), session_id() | nil, query :: String.t()) :: {:ok, String.t()} | {:error, term()}
Functions
@spec capture(runtime_owner(), Gralkor.Capture.t()) :: :ok | {:error, term()}
@spec impl() :: module()
@spec ingest(Gralkor.Ingest.t()) :: :ok | {:error, term()}
@spec ingest(runtime_owner(), Gralkor.Ingest.t()) :: :ok | {:error, term()}
@spec lens!(String.t()) :: Gralkor.Lens.t() | Gralkor.Lens.Replaceable.t()
@spec replace(Gralkor.Replace.t()) :: :ok | {:error, term()}
@spec replace(runtime_owner(), Gralkor.Replace.t()) :: :ok | {:error, term()}
@spec search(Gralkor.Search.t()) :: {:ok, [search_result()]} | {:error, term()}
@spec search(runtime_owner(), Gralkor.Search.t()) :: {:ok, [search_result()]} | {:error, term()}