Documentation
¶
Index ¶
- Variables
- func ComputeSchemaFingerprint(chunkerVersion, embeddingModel string) string
- func ComputeSchemaVersion(chunkerVersion, modelName string) string
- func DecodeVector(b []byte) []float32
- func EncodeVector(v []float32) []byte
- type CodeChunkRecord
- type Edge
- type Node
- type NodeFilter
- type NodeVersion
- type ReplayEvent
- type Session
- type Storage
- type Store
- func (s *Store) AddFileWatch(ctx context.Context, filePath, nodeID, gitHash string) error
- func (s *Store) AddReplayEvent(ctx context.Context, sessionID, data string) error
- func (s *Store) AllEmbeddings(ctx context.Context) (map[string][]float32, error)
- func (s *Store) CheckCycle(ctx context.Context, fromID, toID string) (bool, error)
- func (s *Store) Close() error
- func (s *Store) CountAllEdges(ctx context.Context) (int, error)
- func (s *Store) CountEdges(ctx context.Context, nodeID string) (inbound int, outbound int, err error)
- func (s *Store) CreateCodeIndex(ctx context.Context) error
- func (s *Store) CreateEdge(ctx context.Context, e *Edge) error
- func (s *Store) CreateNode(ctx context.Context, n *Node) error
- func (s *Store) CreateSession(ctx context.Context, sess *Session) error
- func (s *Store) DB() *sql.DB
- func (s *Store) DeleteChunksByPath(ctx context.Context, path string) error
- func (s *Store) DeleteEdge(ctx context.Context, id string) error
- func (s *Store) DeleteEmbedding(ctx context.Context, nodeID string) error
- func (s *Store) DeleteNode(ctx context.Context, id string) error
- func (s *Store) DiffVersions(ctx context.Context, nodeID string, v1, v2 int) (content1, content2 string, err error)
- func (s *Store) EndSession(ctx context.Context, id string, summary string) error
- func (s *Store) FlushAccessLog(ctx context.Context) (int, error)
- func (s *Store) GetEdge(ctx context.Context, id string) (*Edge, error)
- func (s *Store) GetEdgesBetween(ctx context.Context, nodeIDs []string) ([]*Edge, error)
- func (s *Store) GetEdgesFrom(ctx context.Context, nodeID string) ([]*Edge, error)
- func (s *Store) GetEdgesTo(ctx context.Context, nodeID string) ([]*Edge, error)
- func (s *Store) GetEmbedding(ctx context.Context, nodeID string) ([]float32, string, error)
- func (s *Store) GetEmbeddingsBatch(ctx context.Context, offset, limit int) (map[string][]float32, error)
- func (s *Store) GetFileHash(ctx context.Context, path string) (string, error)
- func (s *Store) GetNeighbors(ctx context.Context, nodeID string) ([]*Node, error)
- func (s *Store) GetNode(ctx context.Context, id string) (*Node, error)
- func (s *Store) GetNodeByKey(ctx context.Context, key, project string) (*Node, error)
- func (s *Store) GetNodesBatch(ctx context.Context, ids []string) ([]*Node, error)
- func (s *Store) GetNodesByFile(ctx context.Context, filePath string) ([]*Node, error)
- func (s *Store) GetReplayEvents(ctx context.Context, sessionID string) ([]*ReplayEvent, error)
- func (s *Store) GetVersions(ctx context.Context, nodeID string) ([]*NodeVersion, error)
- func (s *Store) InvalidateEdge(ctx context.Context, id string) error
- func (s *Store) InvalidateStaleChunks(ctx context.Context, currentVersion string) (int, error)
- func (s *Store) ListIndexedPaths(ctx context.Context) ([]string, error)
- func (s *Store) ListNodes(ctx context.Context, f NodeFilter) ([]*Node, error)
- func (s *Store) ListSessions(ctx context.Context, project string, limit int) ([]*Session, error)
- func (s *Store) LogAccess(ctx context.Context, nodeID string) error
- func (s *Store) RefreshCodeIndex(ctx context.Context, paths []string, hashFn func(string) string) (int, error)
- func (s *Store) RollbackToVersion(ctx context.Context, nodeID string, version int) error
- func (s *Store) SaveEmbedding(ctx context.Context, nodeID, model string, vector []float32) error
- func (s *Store) SaveVersion(ctx context.Context, nodeID string, content, changedBy, reason string) error
- func (s *Store) SearchCodeChunksByLanguage(ctx context.Context, query string, languages []string, limit int) ([]*CodeChunkRecord, error)
- func (s *Store) SearchCodeChunksFTS(ctx context.Context, query string, limit int) ([]*CodeChunkRecord, error)
- func (s *Store) SearchCodeChunksHybrid(ctx context.Context, query string, queryVec []float32, limit int, ...) ([]*CodeChunkRecord, error)
- func (s *Store) SearchNodeByHash(ctx context.Context, hash, scope, project string) (*Node, error)
- func (s *Store) SearchNodes(ctx context.Context, query string, limit int) ([]*Node, error)
- func (s *Store) StoreVector(ctx context.Context, chunkID string, vec []float32) error
- func (s *Store) UpdateNode(ctx context.Context, n *Node) error
- func (s *Store) UpdateNodeContent(ctx context.Context, id, newContent string) error
- func (s *Store) UpsertByTopic(ctx context.Context, n *Node, topicKey string) (*Node, bool, error)
- func (s *Store) UpsertCodeChunk(ctx context.Context, chunk *CodeChunkRecord) error
- func (s *Store) WithTx(ctx context.Context, fn func(Storage) error) error
Constants ¶
This section is empty.
Variables ¶
var ( ErrNodeNotFound = errors.New("node not found") ErrEdgeNotFound = errors.New("edge not found") ErrSessionNotFound = errors.New("session not found") ErrCycleDetected = errors.New("cycle detected") ErrDuplicateNode = errors.New("duplicate node") ErrDuplicateEdge = errors.New("duplicate edge") ErrInvalidNodeType = errors.New("invalid node type") ErrInvalidEdgeType = errors.New("invalid edge type") ErrContentTooLong = errors.New("content exceeds maximum length") ErrEmptyContent = errors.New("content cannot be empty") ErrDatabaseLocked = errors.New("database is locked") ErrBatchTooLarge = errors.New("batch size exceeds database limit") ErrVersionNotFound = errors.New("version not found") ErrEmbeddingNotFound = errors.New("embedding not found") )
Domain-specific errors for the storage layer. Callers should use errors.Is() to check for specific error conditions.
Functions ¶
func ComputeSchemaFingerprint ¶
ComputeSchemaFingerprint returns a hex-encoded 128-bit hash of the chunker version and embedding model, suitable for invalidating all chunks when the indexing pipeline changes. Uses SHA-256 truncated to 16 bytes.
func ComputeSchemaVersion ¶
ComputeSchemaVersion produces a version string from the chunker version and embedding model name. It is the first 16 hex chars of a SHA-256 hash.
func DecodeVector ¶
DecodeVector decodes a byte slice from SQLite BLOB to a float32 slice.
func EncodeVector ¶
EncodeVector encodes a float32 slice to a byte slice for SQLite BLOB storage.
Types ¶
type CodeChunkRecord ¶
type CodeChunkRecord struct {
ID string `json:"id"`
Path string `json:"path"`
StartLine int `json:"start_line"`
EndLine int `json:"end_line"`
Content string `json:"content"`
Symbol string `json:"symbol"`
Language string `json:"language"`
Tokens int `json:"tokens"`
FileHash string `json:"file_hash"`
SchemaVersion string `json:"schema_version"`
Vector []byte `json:"vector,omitempty"` // embedding stored as BLOB
}
CodeChunkRecord represents a stored code chunk in the index.
type Edge ¶
type Edge struct {
ID, FromID, ToID, Type, Metadata string
Acyclic bool
Weight float64
ValidAt time.Time // when the fact became true (zero = since creation)
InvalidAt time.Time // when the fact stopped being true (zero = still valid)
CreatedAt time.Time
}
Edge represents a relationship between two nodes in the graph.
type Node ¶
type Node struct {
ID, Type, Content, ContentHash, Summary, Scope, Project, Tags string
Key string // optional unique key per project (upsert semantics)
Pinned bool // pinned nodes always appear in context
Tier int
Confidence float64
AccessCount int
CreatedAt, UpdatedAt, AccessedAt time.Time
SourceSession, SourceAgent string
Version int
}
Node represents a memory node in the Yaad graph.
type NodeFilter ¶
type NodeFilter struct {
Type, Scope, Project string
Tier int
MinConfidence float64
SourceSession string
Pinned *bool // filter by pinned status (nil = no filter)
Limit int // max results (0 = default 1000)
}
NodeFilter specifies criteria for listing nodes.
type NodeVersion ¶
type NodeVersion struct {
NodeID, Content, ChangedBy, Reason string
Version int
ChangedAt time.Time
}
NodeVersion stores a historical version of a node for audit/rollback.
type ReplayEvent ¶
ReplayEvent is a raw tool event stored for session replay.
type Storage ¶
type Storage interface {
// Nodes
CreateNode(ctx context.Context, n *Node) error
GetNode(ctx context.Context, id string) (*Node, error)
GetNodeByKey(ctx context.Context, key, project string) (*Node, error)
GetNodesBatch(ctx context.Context, ids []string) ([]*Node, error)
UpdateNode(ctx context.Context, n *Node) error
UpdateNodeContent(ctx context.Context, id, newContent string) error
DeleteNode(ctx context.Context, id string) error
ListNodes(ctx context.Context, f NodeFilter) ([]*Node, error)
SearchNodes(ctx context.Context, query string, limit int) ([]*Node, error)
SearchNodeByHash(ctx context.Context, hash, scope, project string) (*Node, error)
GetNeighbors(ctx context.Context, nodeID string) ([]*Node, error)
// Edges
CreateEdge(ctx context.Context, e *Edge) error
GetEdge(ctx context.Context, id string) (*Edge, error)
InvalidateEdge(ctx context.Context, id string) error // non-destructive: sets invalid_at = now
DeleteEdge(ctx context.Context, id string) error
GetEdgesFrom(ctx context.Context, nodeID string) ([]*Edge, error)
GetEdgesTo(ctx context.Context, nodeID string) ([]*Edge, error)
GetEdgesBetween(ctx context.Context, nodeIDs []string) ([]*Edge, error)
CountEdges(ctx context.Context, nodeID string) (inbound int, outbound int, err error)
CountAllEdges(ctx context.Context) (int, error)
// Graph queries (encapsulates recursive CTEs)
CheckCycle(ctx context.Context, fromID, toID string) (bool, error)
// Sessions
CreateSession(ctx context.Context, sess *Session) error
EndSession(ctx context.Context, id string, summary string) error
ListSessions(ctx context.Context, project string, limit int) ([]*Session, error)
// Versions
SaveVersion(ctx context.Context, nodeID string, content, changedBy, reason string) error
GetVersions(ctx context.Context, nodeID string) ([]*NodeVersion, error)
// Embeddings
SaveEmbedding(ctx context.Context, nodeID, model string, vector []float32) error
DeleteEmbedding(ctx context.Context, nodeID string) error
AllEmbeddings(ctx context.Context) (map[string][]float32, error)
GetEmbeddingsBatch(ctx context.Context, offset, limit int) (map[string][]float32, error)
// Replay
AddReplayEvent(ctx context.Context, sessionID, data string) error
GetReplayEvents(ctx context.Context, sessionID string) ([]*ReplayEvent, error)
// File watch (staleness tracking)
AddFileWatch(ctx context.Context, filePath, nodeID, gitHash string) error
// AccessLog: lightweight access tracking (batched flush)
LogAccess(ctx context.Context, nodeID string) error
FlushAccessLog(ctx context.Context) (int, error)
// Transactions
WithTx(ctx context.Context, fn func(Storage) error) error
Close() error
}
Storage is the persistence interface used by Engine and other packages. All graph-aware queries (recursive CTEs, cycle detection) are encapsulated behind methods so callers never need raw *sql.DB access.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
func (*Store) AddFileWatch ¶
func (*Store) AddReplayEvent ¶
AddReplayEvent stores a tool event for replay.
func (*Store) AllEmbeddings ¶
AllEmbeddings returns all stored embeddings as (nodeID, vector) pairs.
func (*Store) CheckCycle ¶
CheckCycle uses a recursive CTE to detect if adding from→to would create a cycle among acyclic edges.
func (*Store) CountAllEdges ¶
CountAllEdges returns the total number of edges in the graph.
func (*Store) CountEdges ¶
func (s *Store) CountEdges(ctx context.Context, nodeID string) (inbound int, outbound int, err error)
CountEdges returns inbound and outbound edge counts for a node.
func (*Store) CreateCodeIndex ¶
CreateCodeIndex creates the code_chunks table and its FTS5 virtual table. Safe to call multiple times (uses IF NOT EXISTS).
func (*Store) CreateSession ¶
func (*Store) DeleteChunksByPath ¶
DeleteChunksByPath removes all code chunks for a given file path.
func (*Store) DeleteEmbedding ¶
DeleteEmbedding removes a vector embedding for a node.
func (*Store) DiffVersions ¶
func (s *Store) DiffVersions(ctx context.Context, nodeID string, v1, v2 int) (content1, content2 string, err error)
DiffVersions returns the content of two versions for comparison.
func (*Store) EndSession ¶
func (*Store) FlushAccessLog ¶
FlushAccessLog aggregates access_log entries into nodes.access_count / accessed_at, then truncates the log. Runs atomically within a transaction.
func (*Store) GetEdgesBetween ¶
func (*Store) GetEdgesFrom ¶
func (*Store) GetEdgesTo ¶
func (*Store) GetEmbedding ¶
GetEmbedding retrieves the embedding for a node.
func (*Store) GetEmbeddingsBatch ¶
func (s *Store) GetEmbeddingsBatch(ctx context.Context, offset, limit int) (map[string][]float32, error)
GetEmbeddingsBatch returns a paginated batch of embeddings.
func (*Store) GetFileHash ¶
GetFileHash returns the file hash for the first chunk of the given path.
func (*Store) GetNeighbors ¶
func (*Store) GetNodeByKey ¶
func (*Store) GetNodesBatch ¶
func (*Store) GetNodesByFile ¶
func (*Store) GetReplayEvents ¶
GetReplayEvents returns all events for a session in order.
func (*Store) GetVersions ¶
func (*Store) InvalidateStaleChunks ¶
InvalidateStaleChunks deletes all code chunks whose schema_version does not match currentVersion, returning the count of deleted rows.
func (*Store) ListIndexedPaths ¶
ListIndexedPaths returns all distinct file paths that have indexed chunks.
func (*Store) ListSessions ¶
func (*Store) LogAccess ¶
LogAccess records a lightweight access event (INSERT only, no UPDATE churn).
func (*Store) RefreshCodeIndex ¶
func (s *Store) RefreshCodeIndex(ctx context.Context, paths []string, hashFn func(string) string) (int, error)
RefreshCodeIndex checks each path for staleness by comparing the current file hash (via hashFn) against the stored hash. Returns the count of stale files.
func (*Store) RollbackToVersion ¶
RollbackToVersion restores a node's content to a specific version.
func (*Store) SaveEmbedding ¶
SaveEmbedding stores a vector embedding for a node.
func (*Store) SaveVersion ¶
func (*Store) SearchCodeChunksByLanguage ¶
func (s *Store) SearchCodeChunksByLanguage(ctx context.Context, query string, languages []string, limit int) ([]*CodeChunkRecord, error)
SearchCodeChunksByLanguage performs a full-text search filtered by language. If languages is empty, calls existing SearchCodeChunksFTS. If one language, adds a WHERE language = ? filter. If multiple languages, runs separate queries per language and merges via min-heap.
func (*Store) SearchCodeChunksFTS ¶
func (s *Store) SearchCodeChunksFTS(ctx context.Context, query string, limit int) ([]*CodeChunkRecord, error)
SearchCodeChunksFTS performs a full-text search on code chunks.
func (*Store) SearchCodeChunksHybrid ¶
func (s *Store) SearchCodeChunksHybrid(ctx context.Context, query string, queryVec []float32, limit int, languages []string) ([]*CodeChunkRecord, error)
SearchCodeChunksHybrid performs a hybrid search combining FTS5 ranking with cosine similarity on stored vectors. If languages is non-empty, only chunks in those languages are considered.
func (*Store) SearchNodeByHash ¶
SearchNodeByHash finds a node by content hash + scope + project (dedup check).
func (*Store) SearchNodes ¶
func (*Store) StoreVector ¶
StoreVector saves an embedding vector for a code chunk.
func (*Store) UpdateNodeContent ¶
func (*Store) UpsertByTopic ¶
UpsertByTopic updates an existing node if one with the same project+scope+topic_key exists, otherwise creates a new one. Based on Engram's topic dedup approach. topic_key is stored in the Tags field as "topic:<key>".
func (*Store) UpsertCodeChunk ¶
func (s *Store) UpsertCodeChunk(ctx context.Context, chunk *CodeChunkRecord) error
UpsertCodeChunk inserts or replaces a code chunk record and updates the FTS index.