AgentHarness.Store behaviour (AgentHarness v0.2.0)

Copy Markdown View Source

Persistence boundary for logical agent-session state.

A session is the aggregate root: turns, events, and requests are owned by a session and must not outlive it. Store implementations serialize writes made by a session before making them visible to readers.

Session snapshots are deliberately opaque. This keeps the persistence layer independent of the private session-process state while allowing a durable adapter to restore the public and provider identifiers it needs.

Events are append-only. events/3 uses an exclusive sequence cursor, so after: 7 returns events whose sequence is greater than seven. A :turn_id option asks the Store to filter by turn before applying its cursor and limit.

Public purge rejects a live SessionServer. Core-controlled startup replacement and rollback may call delete_session/2 from a task whose owner is that registered SessionServer; Stores that add their own live-delete guard must allow that owner-bound case.

Summary

Types

event_options()

@type event_options() :: [
  after: non_neg_integer(),
  limit: non_neg_integer() | :infinity,
  turn_id: String.t()
]

owner()

@type owner() :: term()

request_options()

@type request_options() :: [
  turn_id: String.t(),
  status: AgentHarness.Request.status()
]

session_id()

@type session_id() :: String.t()

session_snapshot()

@type session_snapshot() :: term()

Callbacks

append_event(owner, t)

@callback append_event(owner(), AgentHarness.Event.t()) :: :ok | {:error, term()}

delete_session(owner, session_id)

@callback delete_session(owner(), session_id()) :: :ok | {:error, term()}

events(owner, session_id, event_options)

@callback events(owner(), session_id(), event_options()) ::
  {:ok, [AgentHarness.Event.t()]} | {:error, term()}

fetch_request(owner, session_id, t)

@callback fetch_request(owner(), session_id(), String.t()) ::
  {:ok, AgentHarness.Request.t()} | :not_found | {:error, term()}

fetch_session(owner, session_id)

@callback fetch_session(owner(), session_id()) ::
  {:ok, session_snapshot()} | :not_found | {:error, term()}

fetch_turn(owner, session_id, t)

@callback fetch_turn(owner(), session_id(), String.t()) ::
  {:ok, AgentHarness.Turn.t()} | :not_found | {:error, term()}

latest_sequence(owner, session_id)

@callback latest_sequence(owner(), session_id()) ::
  {:ok, non_neg_integer() | nil} | {:error, term()}

list_requests(owner, session_id, request_options)

@callback list_requests(owner(), session_id(), request_options()) ::
  {:ok, [AgentHarness.Request.t()]} | {:error, term()}

list_sessions(owner)

@callback list_sessions(owner()) :: [{session_id(), session_snapshot()}]

list_turns(owner, session_id)

@callback list_turns(owner(), session_id()) ::
  {:ok, [AgentHarness.Turn.t()]} | {:error, term()}

save_request(owner, t)

@callback save_request(owner(), AgentHarness.Request.t()) :: :ok | {:error, term()}

save_session(owner, session_id, session_snapshot)

@callback save_session(owner(), session_id(), session_snapshot()) ::
  :ok | {:error, term()}

save_turn(owner, t)

@callback save_turn(owner(), AgentHarness.Turn.t()) :: :ok | {:error, term()}