import type { MemoryEntry, MemoryScope } from '../types/memory.js'; import { type FileMemoryBackendOptions } from './memory-backend.js'; import type { MemoryBackend } from './memory-backend.js'; interface GraphNode { id: string; entry: MemoryEntry; firstSeen: string; count: number; /** Extracted metadata for fast lookup. */ type?: MemoryEntry['type'] | undefined; tags?: string[] | undefined; priority?: MemoryEntry['priority'] | undefined; } interface GraphEdge { from: string; to: string; /** Why these nodes are related. */ relation: 'co_occurring' | 'similar' | 'same_turn' | 'explicit'; weight: number; ts: string; } export interface GraphMemoryBackendOptions extends FileMemoryBackendOptions { /** * Path to the graph metadata file (edges + node metadata). * Defaults to `/memory-graph.json`. */ graphPath?: string | undefined; } /** * @deprecated Migrate to `SageStore` from the SAGE package, * which provides the same `MemoryBackend` operations (remember, forget, search, * consolidate, list, clear) plus graph support via its integrated * `SageGraph` implementation. * This legacy backend stores entries as markdown bullets in a flat file with a * separate graph.json; SageStore stores structured records in JSONL (or * SQLite) with a dedicated edges.jsonl supporting 12 relation types (supersedes, * contradicts, about_file, etc.) and mutation-locked append. * Migration is NOT drop-in — migrate to SageStore and use its * integrated graph features instead. * * Graph-based memory backend that tracks relationships between entries. * Builds on top of FileMemoryBackend — entries are still persisted as * markdown bullets, but the graph layer adds: * * - Co-occurrence edges (entries from the same remember() batch) * - Content similarity edges (simple Jaccard on word overlap) * - Turn-based edges (entries created in the same LLM turn) * - Graph traversal queries (find related memories) * * The graph metadata persists to `/memory-graph.json`. */ export declare class GraphMemoryBackend implements MemoryBackend { readonly kind = "graph"; private readonly file; private readonly graphFile; private nodes; private edges; private loadedScope; private loaded; /** * Inverted index for O(1) term → node lookup during search. * Built incrementally on remember/forget, rebuilt on loadGraph if absent. * Maps lowercase term (min 3 chars) → Set of node IDs containing that term. */ private invertedIndex; /** Minimum term length to index — avoids noise from 1-2 char fragments. */ private static readonly MIN_TERM_LEN; /** * Promise that resolves when the current in-flight _saveGraph completes. * Tests call flush() to await this before deleting the backend or its temp dir. * Each save operation chains onto the previous one so concurrent saves are serialised. */ private _saveDone; constructor(opts: GraphMemoryBackendOptions); remember(scope: MemoryScope, entry: MemoryEntry, filePath: string): Promise; forget(scope: MemoryScope, query: string, filePath: string): Promise; readAll(scope: MemoryScope, filePath: string): Promise; list(scope: MemoryScope, filePath: string, limit?: number): Promise; search(scope: MemoryScope, query: string, _filePath: string, limit?: number): Promise; clear(scope: MemoryScope, filePath: string): Promise; consolidate(scope: MemoryScope, filePath: string): Promise; /** * Find memories related to the given entry, ordered by edge weight. */ findRelated(scope: MemoryScope, _filePath: string, entryText: string, limit?: number): Promise; /** * Get all edges for visualization or traversal. */ getGraph(): { nodes: GraphNode[]; edges: GraphEdge[]; }; private nodeId; private loadGraph; /** Fire-and-forget graph persistence. Named _saveGraph to signal it must not be awaited. */ private _saveGraph; /** * Wait for all in-flight _saveGraph operations to complete. * Call this before deleting the backend or its temp directory. */ flush(): Promise; /** * Build the inverted index from all currently loaded nodes. * Called on loadGraph() to reconstruct the index after loading from disk. */ private buildInvertedIndex; /** * Index a node in the inverted index. Adds the node's ID to all term entries. */ private indexNode; /** * Remove a node's terms from the inverted index before deleting it. * Used in forget() and when updating existing nodes. */ private removeNodeFromIndex; /** * Update an existing node's entries in the inverted index. * Removes old terms and adds new ones. */ private updateNodeIndex; /** * Extract searchable terms from a memory entry. * Returns lowercase words from text (min length) and full tag strings. */ private extractTerms; } export {}; //# sourceMappingURL=memory-graph-backend.d.ts.map