Mnemosyne.Session (mnemosyne v0.1.6)

Copy Markdown View Source

GenStateMachine managing the lifecycle of a memory session.

States: :idle, :collecting, :extracting, :failed, :ready.

Extraction is spawned under a Task.Supervisor via async_nolink, keeping the session responsive while LLM work happens in the background. Failed state preserves the closed episode for retry.

Summary

Functions

Appends an observation-action pair to the current episode. Blocks until the append completes or the timeout expires.

Like append/3 but returns immediately. Accepts an optional callback that receives :ok or {:error, reason} when the append finishes.

Returns a specification to start this module under a supervisor.

Closes the current episode and starts asynchronous extraction.

Asynchronous close. Returns immediately or queues when busy. The optional callback receives {:ok, :closed} or {:error, reason}.

Commits the session result. In :ready state, applies the extracted changeset to the MemoryStore and transitions to :idle. In :failed state, retries the extraction by re-spawning the extraction task.

Asynchronous commit. Returns immediately with :ok when the session is idle or ready, or queues the operation when extraction is in progress. The optional callback receives {:ok, :committed} or {:error, reason} when the op runs.

Discards the extraction result and returns to :idle.

Asynchronous discard. Returns immediately or queues when busy. The optional callback receives {:ok, :discarded} or {:error, reason}.

Returns session context for use by MemoryStore.recall_in_context.

Like get_context/1 but looks up the session in the given registry.

Returns the unique session ID.

Opens a new episode with the given goal, transitioning from :idle to :collecting.

Asynchronous start_episode. Returns immediately or queues when busy. The optional callback receives {:ok, :started} or {:error, reason}.

Returns the current state atom (:idle, :collecting, :extracting, :ready, :failed).

Types

append_caller()

@type append_caller() ::
  {:reply, GenServer.from()} | {:callback, (append_result() -> any())}

append_result()

@type append_result() :: :ok | {:error, Mnemosyne.Errors.error()}

op_callback()

@type op_callback() ::
  ({:ok, term()} | {:error, Mnemosyne.Errors.error()} -> any()) | nil

state()

@type state() :: :idle | :collecting | :extracting | :ready | :failed

t()

@type t() :: %Mnemosyne.Session{
  append_caller: append_caller() | nil,
  append_queue: :queue.queue(),
  append_task: reference() | nil,
  changeset: Mnemosyne.Graph.Changeset.t() | nil,
  committed_step_indices: MapSet.t(non_neg_integer()),
  config: Mnemosyne.Config.t() | nil,
  embedding: module() | nil,
  episode: Mnemosyne.Pipeline.Episode.t() | nil,
  extraction_task: reference() | nil,
  flush_timer: reference() | nil,
  flush_triggered: %{required(String.t()) => true},
  id: String.t() | nil,
  llm: module() | nil,
  memory_store: GenServer.server() | nil,
  notifier: module() | nil,
  pending_ops: :queue.queue(),
  prev_trajectory_id: String.t() | nil,
  registry: module() | nil,
  repo_id: String.t() | nil,
  session_timer: reference() | nil,
  stopping: boolean(),
  task_supervisor: module() | nil,
  trajectory_tasks: %{
    required(reference()) => {String.t(), [non_neg_integer()]}
  }
}

Functions

append(server, observation, action)

@spec append(GenServer.server(), String.t(), String.t()) ::
  :ok | {:error, Mnemosyne.Errors.error()}

Appends an observation-action pair to the current episode. Blocks until the append completes or the timeout expires.

append_async(server, observation, action, callback \\ nil)

@spec append_async(
  GenServer.server(),
  String.t(),
  String.t(),
  (append_result() -> any()) | nil
) :: :ok

Like append/3 but returns immediately. Accepts an optional callback that receives :ok or {:error, reason} when the append finishes.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

close(server)

@spec close(GenServer.server()) :: :ok | {:error, Mnemosyne.Errors.error()}

Closes the current episode and starts asynchronous extraction.

close_async(server, callback \\ nil)

@spec close_async(GenServer.server(), op_callback()) ::
  :ok | {:error, Mnemosyne.Errors.Framework.SessionError.t()}

Asynchronous close. Returns immediately or queues when busy. The optional callback receives {:ok, :closed} or {:error, reason}.

commit(server)

@spec commit(GenServer.server()) :: :ok | {:error, Mnemosyne.Errors.error()}

Commits the session result. In :ready state, applies the extracted changeset to the MemoryStore and transitions to :idle. In :failed state, retries the extraction by re-spawning the extraction task.

commit_async(server, callback \\ nil)

@spec commit_async(GenServer.server(), op_callback()) ::
  :ok | {:error, Mnemosyne.Errors.Framework.SessionError.t()}

Asynchronous commit. Returns immediately with :ok when the session is idle or ready, or queues the operation when extraction is in progress. The optional callback receives {:ok, :committed} or {:error, reason} when the op runs.

discard(server)

@spec discard(GenServer.server()) ::
  :ok | {:error, Mnemosyne.Errors.Framework.SessionError.t()}

Discards the extraction result and returns to :idle.

discard_async(server, callback \\ nil)

@spec discard_async(GenServer.server(), op_callback()) ::
  :ok | {:error, Mnemosyne.Errors.Framework.SessionError.t()}

Asynchronous discard. Returns immediately or queues when busy. The optional callback receives {:ok, :discarded} or {:error, reason}.

get_context(server)

@spec get_context(GenServer.server() | String.t()) :: {:ok, map() | nil}

Returns session context for use by MemoryStore.recall_in_context.

Accepts a pid/name for direct calls, or a string session_id looked up via Mnemosyne.Registry (the default production registry). Returns {:ok, %{goal: ..., recent_steps: [...]}} or {:ok, nil} when idle.

get_context(session_id, registry)

@spec get_context(String.t(), atom()) :: {:ok, map() | nil}

Like get_context/1 but looks up the session in the given registry.

id(server)

@spec id(GenServer.server()) :: String.t()

Returns the unique session ID.

start_episode(server, goal)

@spec start_episode(GenServer.server(), String.t()) ::
  :ok | {:error, Mnemosyne.Errors.Framework.SessionError.t()}

Opens a new episode with the given goal, transitioning from :idle to :collecting.

start_episode_async(server, goal, callback \\ nil)

@spec start_episode_async(GenServer.server(), String.t(), op_callback()) ::
  :ok | {:error, Mnemosyne.Errors.Framework.SessionError.t()}

Asynchronous start_episode. Returns immediately or queues when busy. The optional callback receives {:ok, :started} or {:error, reason}.

state(server)

@spec state(GenServer.server()) :: state()

Returns the current state atom (:idle, :collecting, :extracting, :ready, :failed).