Class SqliteMemoryGraph

SQLite-backed implementation of IMemoryGraph.

Thread safety: inherits the underlying adapter's concurrency model. Writes serialise automatically through WAL when using SQLite-backed adapters.

Usage:

const brain = await SqliteBrain.open('/path/to/brain.sqlite');
const graph = new SqliteMemoryGraph(brain);
await graph.initialize();

await graph.addNode('mem-1', { type: 'episodic', scope: 'session', scopeId: 's1', strength: 1.0, createdAt: Date.now() });
await graph.addEdge({ sourceId: 'mem-1', targetId: 'mem-2', type: 'SAME_TOPIC', weight: 0.8, createdAt: Date.now() });

const activated = await graph.spreadingActivation(['mem-1']);

Implements

Constructors

Methods

  • Add a memory node to the graph.

    The node is persisted to knowledge_nodes (type = 'memory_graph') with the metadata serialised into the properties JSON column. If a node with the same memoryId already exists it is silently replaced (upsert).

    Parameters

    • memoryId: string

      Unique identifier for the memory trace this node represents.

    • metadata: MemoryGraphNodeMeta

      Structural metadata describing the memory.

    Returns Promise<void>

  • Remove a node and all its incident edges from the graph.

    Edges referencing the removed node are deleted from both SQLite and the in-memory cache to keep the graph consistent.

    Parameters

    • memoryId: string

      ID of the node to remove.

    Returns Promise<void>

  • Add a directed edge between two memory nodes.

    If an edge with the same (sourceId, targetId) pair already exists it is replaced (upsert by composite key). The underlying SQLite row is identified by a deterministic UUID derived from the source/target pair so that repeated upserts land on the same row.

    Parameters

    • edge: MemoryEdge

      Edge descriptor including type, weight, and timestamp.

    Returns Promise<void>

  • Run spreading activation from a set of seed nodes.

    Implements Anderson's ACT-R spreading activation model using BFS:

    1. Each seed node starts with activation = 1.0.
    2. When a node propagates to a neighbour, the neighbour's activation receives: parentActivation * (1 - decayPerHop) * edgeWeight.
    3. If a node is reached by multiple paths, the maximum activation is kept.
    4. Nodes below activationThreshold are not expanded further.
    5. BFS stops at depth maxDepth.

    Seed nodes are excluded from the returned list (they are the query, not the result).

    Parameters

    • seedIds: string[]

      IDs of the memory nodes that trigger the activation.

    • Optional config: SpreadingActivationConfig

      Optional tuning parameters.

    Returns Promise<ActivatedNode[]>

    Activated nodes sorted by activation descending, capped at maxResults.

  • Record that a set of memories were activated together (Hebbian learning).

    For every unordered pair (A, B) in memoryIds, a CO_ACTIVATED edge is upserted:

    • If no edge exists, it is created with weight = learningRate.
    • If an edge already exists, its weight is incremented by learningRate and capped at 1.0.

    This implements the Hebbian rule "neurons that fire together wire together" at the memory graph level, gradually strengthening associations between memories that are frequently retrieved in the same context.

    Parameters

    • memoryIds: string[]

      IDs of co-activated memories.

    • learningRate: number = 0.1

      Weight increment per co-activation event.

    Returns Promise<void>

    Default

    0.1
    
  • Return all CONTRADICTS edges incident to a given memory node.

    A CONTRADICTS edge signals that two memories express mutually incompatible beliefs or facts. The consolidation engine uses this to trigger conflict-resolution passes.

    Parameters

    • memoryId: string

      The memory node to check for contradictions.

    Returns MemoryEdge[]

    Array of CONTRADICTS edges (may be empty).

  • Detect connected components (clusters) in the memory graph.

    Uses path-compressed Union-Find over all edges. Components are filtered to those with at least minSize members.

    The centroidId of each cluster is the member with the highest total incident edge weight (most central node). If the cluster has only one member, centroidId equals that member.

    The density of a cluster is computed as: actualEdges / maxPossibleEdges where maxPossibleEdges = n*(n-1). For single-member clusters, density = 0.

    Parameters

    • minSize: number = 2

      Minimum component size to include.

    Returns Promise<MemoryCluster[]>

    Array of MemoryCluster objects.

    Default

    2