Planck.Agent.SessionStore (Planck.Agent v0.1.8)

Copy Markdown View Source

Database operations for an agent's conversation history.

All functions that persist or load messages from the session SQLite database live here. Planck.Agent calls these helpers and applies the returned data to its own state — there is no state mutation in this module.

Summary

Functions

Persist any in-memory messages that have not yet been written to the session.

Load the message history for agent_id from session_id.

Persist msg to the session and return it with its database ID set.

Save accumulated usage and cost for the agent to the session metadata store.

Remove the last row from rows if it is an orphaned tool-call turn.

Functions

flush_unpersisted(session_id, agent_id, messages)

@spec flush_unpersisted(String.t() | nil, String.t(), [Planck.Agent.Message.t()]) ::
  :flushed | :noop

Persist any in-memory messages that have not yet been written to the session.

Unpersisted messages are identified by a binary (UUID) id — messages written to the DB receive an integer id. Returns :flushed when at least one message was written, :noop when all messages were already persisted.

Always returns :noop for ephemeral agents (session_id: nil).

load_messages(session_id, agent_id, opts \\ [])

@spec load_messages(String.t(), String.t(), keyword()) ::
  {:ok, [Planck.Agent.Message.t()]} | :error

Load the message history for agent_id from session_id.

Returns {:ok, messages} on success, or :error when the session is unavailable.

Pass strip_orphans: true to remove the last message if it is an assistant turn with unanswered tool calls — this repairs state after a crash.

persist_message(session_id, agent_id, msg)

@spec persist_message(String.t() | nil, String.t(), Planck.Agent.Message.t()) ::
  Planck.Agent.Message.t()

Persist msg to the session and return it with its database ID set.

Returns msg unchanged for ephemeral agents (session_id: nil) or when the session append fails.

persist_usage(session_id, agent_id, usage)

@spec persist_usage(String.t() | nil, String.t(), Planck.Agent.Usage.t()) :: :ok

Save accumulated usage and cost for the agent to the session metadata store.

No-op for ephemeral agents (session_id: nil).

strip_orphaned_tool_call(session_id, rows)

@spec strip_orphaned_tool_call(String.t() | nil, [map()]) :: [map()]

Remove the last row from rows if it is an orphaned tool-call turn.

A turn is orphaned when the last assistant message contains tool calls but has no following tool-result message — the agent crashed mid-execution. The orphan is also truncated from the database when session_id is non-nil.