AgentSessionManager.Ports.QueryAPI behaviour (AgentSessionManager v0.8.0)

Copy Markdown View Source

Read-only query interface for historical session data.

Provides cross-session search, aggregation, and export capabilities beyond the single-session cursor reads in SessionStore.

Callbacks

Usage

{:ok, %{sessions: sessions, cursor: cursor}} =
  QueryAPI.search_sessions({EctoQueryAPI, MyApp.Repo}, agent_id: "agent-1", limit: 20)

{:ok, stats} = QueryAPI.get_session_stats({EctoQueryAPI, MyApp.Repo}, "ses_abc123")

Summary

Callbacks

Count events matching filters without loading them.

Export a session's complete data (session + runs + events) as a map.

Get cost summary across runs.

Get aggregate statistics for a session.

Get token usage summary across runs.

Search events across sessions with rich filters.

Search runs across sessions.

Search sessions with rich filters.

Types

context()

@type context() :: term()

cursor()

@type cursor() :: String.t() | nil

query_ref()

@type query_ref() :: {module(), context()}

Callbacks

count_events(context, keyword)

@callback count_events(
  context(),
  keyword()
) :: {:ok, non_neg_integer()} | {:error, AgentSessionManager.Core.Error.t()}

Count events matching filters without loading them.

Same filter options as search_events/2.

export_session(context, session_id, keyword)

@callback export_session(context(), session_id :: String.t(), keyword()) ::
  {:ok, map()} | {:error, AgentSessionManager.Core.Error.t()}

Export a session's complete data (session + runs + events) as a map.

Options

  • :include_artifacts — include artifact metadata (default: false)

get_cost_summary(context, keyword)

@callback get_cost_summary(
  context(),
  keyword()
) :: {:ok, map()} | {:error, AgentSessionManager.Core.Error.t()}

Get cost summary across runs.

Options

  • :session_id — scope to session
  • :agent_id — scope to agent
  • :provider — filter by provider
  • :since — DateTime lower bound
  • :until — DateTime upper bound
  • :pricing_table — override default pricing (optional)

Returns a map with:

  • total_cost_usd — float
  • run_count — integer
  • by_provider — per-provider cost breakdown
  • by_model — per-model cost breakdown
  • unmapped_runs — count of runs without cost

get_session_stats(context, session_id)

@callback get_session_stats(context(), session_id :: String.t()) ::
  {:ok, map()} | {:error, AgentSessionManager.Core.Error.t()}

Get aggregate statistics for a session.

Returns a map with:

  • event_count — total events
  • run_count — total runs
  • token_totals%{input_tokens: n, output_tokens: n, total_tokens: n}
  • providers_used — list of provider names
  • first_event_at — earliest event timestamp
  • last_event_at — latest event timestamp
  • status_counts%{completed: 3, failed: 1, ...} (run statuses)

get_usage_summary(context, keyword)

@callback get_usage_summary(
  context(),
  keyword()
) :: {:ok, map()} | {:error, AgentSessionManager.Core.Error.t()}

Get token usage summary across runs.

Options

  • :session_id — scope to session
  • :provider — filter by provider
  • :since — DateTime lower bound
  • :until — DateTime upper bound

Returns a map with:

  • total_input_tokens — integer
  • total_output_tokens — integer
  • total_tokens — integer
  • run_count — integer
  • by_provider%{"claude" => %{...}, "codex" => %{...}}

search_events(context, keyword)

@callback search_events(
  context(),
  keyword()
) ::
  {:ok, %{events: [AgentSessionManager.Core.Event.t()], cursor: cursor()}}
  | {:error, AgentSessionManager.Core.Error.t()}

Search events across sessions with rich filters.

Options

  • :session_ids — list of session IDs
  • :run_ids — filter by specific runs
  • :types — filter by event types (atom or list)
  • :providers — filter by provider
  • :since — events after this DateTime
  • :until — events before this DateTime
  • :correlation_id — filter by correlation ID
  • :order_by:sequence_asc (default) | :timestamp_asc | :timestamp_desc

  • :limit — max results (default: 100)
  • :cursor — opaque cursor from previous page

search_runs(context, keyword)

@callback search_runs(
  context(),
  keyword()
) ::
  {:ok, %{runs: [AgentSessionManager.Core.Run.t()], cursor: cursor()}}
  | {:error, AgentSessionManager.Core.Error.t()}

Search runs across sessions.

Options

  • :session_id — scope to single session
  • :provider — filter by provider
  • :status — filter by status
  • :started_after — runs started after this DateTime
  • :started_before — runs started before this DateTime
  • :min_tokens — minimum total_tokens
  • :order_by:started_at_desc (default) | :started_at_asc | :token_usage_desc

  • :limit — max results (default: 50)
  • :cursor — opaque cursor from previous page

search_sessions(context, keyword)

@callback search_sessions(
  context(),
  keyword()
) ::
  {:ok,
   %{
     sessions: [AgentSessionManager.Core.Session.t()],
     cursor: cursor(),
     total_count: non_neg_integer()
   }}
  | {:error, AgentSessionManager.Core.Error.t()}

Search sessions with rich filters.

Options

  • :agent_id — filter by agent
  • :status — filter by status (atom or list)
  • :provider — filter by provider that executed runs in this session
  • :tags — filter by tags (all must match)
  • :created_after — sessions created after this DateTime
  • :created_before — sessions created before this DateTime
  • :include_deleted — include soft-deleted sessions (default: false)
  • :order_by:created_at_asc | :created_at_desc | :updated_at_desc (default)

  • :limit — max results (default: 50)
  • :cursor — opaque cursor from previous page

Functions

count_events(query_ref, opts \\ [])

@spec count_events(
  query_ref(),
  keyword()
) :: {:ok, non_neg_integer()} | {:error, AgentSessionManager.Core.Error.t()}

export_session(query_ref, session_id, opts \\ [])

@spec export_session(query_ref(), String.t(), keyword()) ::
  {:ok, map()} | {:error, AgentSessionManager.Core.Error.t()}

get_cost_summary(query_ref, opts \\ [])

@spec get_cost_summary(
  query_ref(),
  keyword()
) :: {:ok, map()} | {:error, AgentSessionManager.Core.Error.t()}

get_session_stats(query_ref, session_id)

@spec get_session_stats(query_ref(), String.t()) ::
  {:ok, map()} | {:error, AgentSessionManager.Core.Error.t()}

get_usage_summary(query_ref, opts \\ [])

@spec get_usage_summary(
  query_ref(),
  keyword()
) :: {:ok, map()} | {:error, AgentSessionManager.Core.Error.t()}

search_events(query_ref, opts \\ [])

@spec search_events(
  query_ref(),
  keyword()
) ::
  {:ok, %{events: [AgentSessionManager.Core.Event.t()], cursor: cursor()}}
  | {:error, AgentSessionManager.Core.Error.t()}

search_runs(query_ref, opts \\ [])

@spec search_runs(
  query_ref(),
  keyword()
) ::
  {:ok, %{runs: [AgentSessionManager.Core.Run.t()], cursor: cursor()}}
  | {:error, AgentSessionManager.Core.Error.t()}

search_sessions(query_ref, opts \\ [])

@spec search_sessions(
  query_ref(),
  keyword()
) ::
  {:ok,
   %{
     sessions: [AgentSessionManager.Core.Session.t()],
     cursor: cursor(),
     total_count: non_neg_integer()
   }}
  | {:error, AgentSessionManager.Core.Error.t()}