Skip to content

mnesis.store.summary_dag

summary_dag

Logical DAG adapter over ImmutableStore for summary node management.

SummaryDAGStore

SummaryDAGStore(store: ImmutableStore)

Manages the logical DAG of summary nodes.

Summary nodes are persisted to two places:

  1. The messages table (is_summary=True) — read by ContextBuilder to inject summaries into the active context window.
  2. The summary_nodes table — stores the full DAG: kind, parent_node_ids (JSON array), and superseded flag. This is the source of truth for DAG relationships and survives session restarts.

Superseded nodes are tracked in an in-memory set (_superseded_ids) for fast within-session filtering, and persisted to summary_nodes.superseded so the state is recoverable after a process restart.

mark_superseded async

mark_superseded(node_ids: list[str]) -> None

Mark one or more summary nodes as superseded by a condensed node.

Updates both the in-memory set (for fast within-session filtering) and the summary_nodes table (so state survives a restart).

Parameters:

Name Type Description Default
node_ids list[str]

IDs of the summary nodes consumed by a condensation.

required

get_active_nodes async

get_active_nodes(session_id: str) -> list[SummaryNode]

Return all active (non-superseded) summary nodes for a session.

Queries summary_nodes WHERE superseded=0 to recover DAG state after a restart, then populates each node's content from the corresponding message parts. Also applies the in-memory superseded set for nodes marked superseded within the current session but not yet flushed (should not happen in practice, but guards against concurrent writes).

Parameters:

Name Type Description Default
session_id str

The session to query.

required

Returns:

Type Description
list[SummaryNode]

List of SummaryNode objects in creation order (created_at ASC).

get_latest_node async

get_latest_node(session_id: str) -> SummaryNode | None

Return the most recently created active summary node, or None.

Reads from summary_nodes to respect DAG supersession correctly, including across restarts.

Parameters:

Name Type Description Default
session_id str

The session to query.

required

Returns:

Type Description
SummaryNode | None

The latest active SummaryNode, or None.

get_coverage_gaps async

get_coverage_gaps(session_id: str) -> list[MessageSpan]

Return spans of messages not covered by any summary node.

In Phase 1, there is at most one summary node (the most recent), so the only gap is the tail of messages after that node.

Parameters:

Name Type Description Default
session_id str

The session to query.

required

Returns:

Type Description
list[MessageSpan]

List of MessageSpan objects representing uncovered message ranges.

insert_node async

insert_node(
    node: SummaryNode, *, id_generator: Callable[[], str]
) -> SummaryNode

Persist a new summary node.

Writes: - A Message with is_summary=True (read by ContextBuilder). - A TextPart with the summary content. - A CompactionMarkerPart with metadata. - A row in summary_nodes with kind, parent_node_ids (JSON), and superseded=0 (the DAG persistence added in Phase 3).

Parameters:

Name Type Description Default
node SummaryNode

The SummaryNode to persist. node.id must be a valid message ID generated by make_id("msg").

required
id_generator Callable[[], str]

Callable that returns new unique part IDs.

required

Returns:

Type Description
SummaryNode

The persisted node (unmodified).

get_node_by_id async

get_node_by_id(node_id: str) -> SummaryNode | None

Fetch a specific summary node by ID.

Parameters:

Name Type Description Default
node_id str

The message ID of the summary node.

required

Returns:

Type Description
SummaryNode | None

The SummaryNode, or None if not found or not a summary.