MingaAgent.SessionStore (Minga v0.1.0)

Copy Markdown View Source

Persists agent conversations to disk as JSON files.

Each session is saved as {session_id}.json in the sessions directory (~/.config/minga/agent/sessions/ by default). Files are written atomically via a temp file + rename to avoid corruption on crash.

The store is stateless: all functions operate directly on the filesystem. The Session GenServer calls save/2 on a debounced timer, and the picker calls list/0 to scan the directory for past sessions.

Summary

Types

Full session data for save/load.

Session metadata for the picker (without full message content).

Functions

Deletes all saved sessions.

Deletes a saved session.

Lists all saved sessions as metadata (without full messages).

Loads a session from disk.

Prunes sessions older than days days.

Saves a session to disk.

Returns the sessions directory path.

Types

session_data()

@type session_data() :: %{
  :id => String.t(),
  :timestamp => String.t(),
  :model_name => String.t(),
  :messages => [MingaAgent.Message.t()],
  :usage => MingaAgent.TurnUsage.t(),
  optional(:last_message_at) => String.t(),
  optional(:title) => String.t(),
  optional(:remote_token) => String.t() | nil,
  optional(:provider_name) => String.t(),
  optional(:branches) => [MingaAgent.Branch.t()],
  optional(:message_ids) => [pos_integer()],
  optional(:pinned_ids) => MapSet.t(pos_integer()),
  optional(:memory) => String.t() | nil
}

Full session data for save/load.

session_meta()

@type session_meta() :: %{
  id: String.t(),
  timestamp: String.t(),
  last_message_at: String.t(),
  title: String.t(),
  model_name: String.t(),
  provider_name: String.t(),
  preview: String.t(),
  recent_messages: String.t(),
  message_count: non_neg_integer(),
  turn_count: non_neg_integer(),
  cost: float()
}

Session metadata for the picker (without full message content).

Functions

clear_all(config_dir \\ nil)

@spec clear_all(String.t() | nil) :: :ok

Deletes all saved sessions.

delete(session_id, config_dir \\ nil)

@spec delete(String.t(), String.t() | nil) :: :ok | {:error, term()}

Deletes a saved session.

list(config_dir \\ nil)

@spec list(String.t() | nil) :: [session_meta()]

Lists all saved sessions as metadata (without full messages).

Returns sessions sorted by last message timestamp, most recent first.

load(session_id, config_dir \\ nil)

@spec load(String.t(), String.t() | nil) :: {:ok, session_data()} | {:error, term()}

Loads a session from disk.

Returns {:ok, session_data} or {:error, reason}.

prune(days, config_dir \\ nil)

@spec prune(non_neg_integer(), String.t() | nil) :: non_neg_integer()

Prunes sessions older than days days.

Returns the number of sessions deleted.

save(data, config_dir \\ nil)

@spec save(session_data(), String.t() | nil) :: :ok | {:error, term()}

Saves a session to disk.

Creates the sessions directory if it doesn't exist. Writes atomically via a temp file to avoid corruption.

sessions_dir(config_dir \\ nil)

@spec sessions_dir(String.t() | nil) :: String.t()

Returns the sessions directory path.