engine

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 5, 2026 License: MIT Imports: 27 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultDecayConfig = DecayConfig{
	HalfLifeDays:  30,
	MinConfidence: 0.1,
	BoostOnAccess: 0.2,
}

Functions

func BoostNode

func BoostNode(ctx context.Context, store storage.Storage, id string, boost float64) error

BoostNode increases confidence of a node on access (capped at 1.0).

func FormatContext

func FormatContext(nodes []*storage.Node) string

FormatContext formats nodes as a markdown context block for injection. Uses tiered injection (Cursor-inspired):

  • Pinned: full content always shown
  • Hot tier (tier 1): full content
  • Warm tier (tier 2): summary/gloss only (full content available via recall)
  • Cold tier: omitted from context

func GarbageCollect

func GarbageCollect(ctx context.Context, store storage.Storage, cfg DecayConfig) (int, error)

GarbageCollect removes nodes below min_confidence (except anchors: file/entity).

func IsValidNodeType

func IsValidNodeType(typ string) bool

IsValidNodeType reports whether typ is a recognized node type.

func RunDecay

func RunDecay(ctx context.Context, store storage.Storage, cfg DecayConfig) error

RunDecay applies half-life decay to all nodes in the store. Orphan nodes (0 edges) and superseded nodes decay 2× faster.

func TrimToTokenBudget

func TrimToTokenBudget(nodes []*storage.Node, budget int) []*storage.Node

TrimToTokenBudget trims a node list to fit within a token budget. Approximation: 1 token ≈ 4 characters.

Types

type AccessTracker

type AccessTracker struct {
	// contains filtered or unexported fields
}

AccessTracker batches node access events to reduce SQLite UPDATE churn. Instead of updating nodes.access_count on every recall (which causes write contention under concurrent load), it INSERTs lightweight rows into access_log and periodically flushes them in a single aggregated UPDATE.

func NewAccessTracker

func NewAccessTracker(store storage.Storage, interval time.Duration) *AccessTracker

NewAccessTracker creates a tracker that flushes every interval.

func (*AccessTracker) Flush

func (at *AccessTracker) Flush(ctx context.Context)

Flush immediately applies all pending access counts to nodes.

func (*AccessTracker) Log

func (at *AccessTracker) Log(ctx context.Context, nodeID string)

Log records an access for the given node ID (best-effort, non-blocking).

func (*AccessTracker) Stop

func (at *AccessTracker) Stop()

Stop halts the background flusher. Safe to call multiple times.

type ConflictCandidate

type ConflictCandidate struct {
	NodeID  string
	Content string
	Score   float64
}

ConflictCandidate represents a potential conflicting node found via FTS.

type DecayConfig

type DecayConfig struct {
	HalfLifeDays  float64 // default 30
	MinConfidence float64 // default 0.1 — below this, eligible for GC
	BoostOnAccess float64 // default 0.2
}

DecayConfig controls decay behaviour.

type EdgeInput

type EdgeInput struct {
	ToID string
	Type string
}

EdgeInput describes an edge to create alongside a node.

type Engine

type Engine struct {
	DecayConfig DecayConfig
	// contains filtered or unexported fields
}

Engine is the core memory engine wrapping graph + storage.

func New

func New(store storage.Storage, g graph.Graph) *Engine

New creates a memory engine.

func (*Engine) Close

func (e *Engine) Close()

Close shuts down the engine and its background workers.

func (*Engine) Compact

func (e *Engine) Compact(ctx context.Context, project string) (int, error)

Compact merges low-confidence memories to keep the graph lean.

func (*Engine) CompressSession

func (e *Engine) CompressSession(ctx context.Context, sessionID, project string) (*storage.Node, error)

CompressSession creates a session summary node linking all memories from the session.

func (*Engine) Context

func (e *Engine) Context(ctx context.Context, project string) (*RecallResult, error)

Context returns the hot-tier subgraph for session start injection. Pinned nodes always appear first (guaranteed 500-token budget), followed by hot-tier and active tasks filling the remaining budget.

func (*Engine) Feedback

func (e *Engine) Feedback(ctx context.Context, id string, action FeedbackAction, newContent string) error

Feedback applies user feedback to a memory node.

func (*Engine) FindConflictCandidates

func (e *Engine) FindConflictCandidates(ctx context.Context, nodeID, content string, limit int) ([]ConflictCandidate, error)

FindConflictCandidates searches for existing nodes that may conflict with the given content. Uses FTS search scoped to the same node type, returning candidates above a score threshold.

func (*Engine) Forget

func (e *Engine) Forget(ctx context.Context, id string) error

Forget archives a node by setting confidence to 0.

func (*Engine) FusedRecall

func (e *Engine) FusedRecall(ctx context.Context, opts RecallOpts) (*RecallResult, error)

FusedRecall performs multi-signal retrieval combining:

  1. BM25 keyword search (via existing SearchNodes FTS5)
  2. Graph traversal (via existing IntentBFS from seed nodes)
  3. Recency signal (recently accessed/modified nodes)

Then fuses results using Reciprocal Rank Fusion (RRF).

This is inspired by mem0's multi-signal retrieval architecture which combines semantic search, BM25, and entity-graph traversal with RRF to produce higher-quality recall than any single signal alone.

Unlike the existing Recall method (which uses BM25 seeds then graph expansion with a confidence*recency heuristic), FusedRecall treats each signal as an independent ranked list and merges them with a principled rank-fusion algorithm. This avoids the score-space mismatch problem where BM25 scores, graph distances, and timestamps are on different scales.

func (*Engine) GetMemoryStats

func (e *Engine) GetMemoryStats(ctx context.Context) (*MemoryStats, error)

GetMemoryStats returns aggregate statistics about the memory graph.

func (*Engine) GetMetrics

func (e *Engine) GetMetrics() Metrics

GetMetrics returns a copy of the engine's operational metrics.

func (*Engine) GetNodeHistory

func (e *Engine) GetNodeHistory(ctx context.Context, nodeID string) ([]NodeHistoryEntry, error)

GetNodeHistory returns the version history of a memory node.

func (*Engine) GetUserProfile

func (e *Engine) GetUserProfile(ctx context.Context, project string) (*UserProfile, error)

GetUserProfile returns the user profile for a project, built from preference nodes.

func (*Engine) Graph

func (e *Engine) Graph() graph.Graph

Graph returns the underlying graph engine.

func (*Engine) MentalModel

func (e *Engine) MentalModel(ctx context.Context, project string) (*mental.Model, error)

MentalModel generates an auto-evolving project summary.

func (*Engine) PendingNodes

func (e *Engine) PendingNodes(ctx context.Context, project string, threshold float64) ([]*storage.Node, error)

PendingNodes returns low-confidence nodes that may need review. Limited to 1000 nodes to prevent unbounded memory use on large graphs.

func (*Engine) Profile

func (e *Engine) Profile(ctx context.Context, project string) (*profile.Profile, error)

Profile returns an auto-maintained user/project profile (static facts + dynamic context).

func (*Engine) Query

func (e *Engine) Query(ctx context.Context, question string, project string) (*QueryResult, error)

Query answers a natural language question by retrieving relevant memories and synthesizing an answer from them. No LLM required — uses template-based synthesis from high-confidence retrieved nodes.

How it works:

  1. Parse the question — classify intent using the existing intent package
  2. Retrieve — call FusedRecall with the question as the query
  3. Rank and filter — keep only nodes with confidence > 0.3
  4. Synthesize — format retrieved memories into a coherent answer using intent-specific templates
  5. Calculate confidence — average confidence of the used nodes

func (*Engine) Recall

func (e *Engine) Recall(ctx context.Context, opts RecallOpts) (*RecallResult, error)

Recall performs graph-aware hybrid search: BM25 seed → graph expand → rank.

func (*Engine) Remember

func (e *Engine) Remember(ctx context.Context, in RememberInput) (*storage.Node, error)

Remember creates a memory node with privacy filtering, dedup, and entity extraction.

func (*Engine) Rollback

func (e *Engine) Rollback(ctx context.Context, id string, version int) error

Rollback restores a node to a previous version.

func (e *Engine) SelfLink(ctx context.Context, node *storage.Node)

SelfLink finds existing nodes semantically related to the new node and creates typed edges. Inspired by A-MEM's Zettelkasten self-organizing approach. Runs as a best-effort step during Remember() — failures don't block storage.

func (*Engine) StartSession

func (e *Engine) StartSession(ctx context.Context, project, agent string) (string, error)

StartSession creates a new session record and returns its ID.

func (*Engine) Status

func (e *Engine) Status(ctx context.Context, project string) (*Status, error)

func (*Engine) Store

func (e *Engine) Store() storage.Storage

Store returns the underlying store.

func (*Engine) UpdateUserPreference

func (e *Engine) UpdateUserPreference(ctx context.Context, project, key, value string) error

UpdateUserPreference stores or updates a single preference as a yaad node.

func (*Engine) WithSummarizer

func (e *Engine) WithSummarizer(s compact.Summarizer) *Engine

WithSummarizer sets a custom summarizer for compaction (e.g., LLM-backed).

type Entity

type Entity struct {
	Name string
	Type string // "file" or "entity"
}

Entity represents an auto-extracted entity from content.

func ExtractEntities

func ExtractEntities(content string) []Entity

ExtractEntities pulls file paths, packages, functions, and classes from content.

type FeedbackAction

type FeedbackAction string

FeedbackAction represents what to do with a pending memory.

const (
	FeedbackApprove FeedbackAction = "approve"
	FeedbackEdit    FeedbackAction = "edit"
	FeedbackDiscard FeedbackAction = "discard"
)

type HybridSearch

type HybridSearch struct {
	// contains filtered or unexported fields
}

HybridSearch performs 3-stage retrieval: BM25 → vector → graph expansion → RRF fusion.

func NewHybridSearch

func NewHybridSearch(store storage.Storage, g graph.Graph, provider embeddings.Provider) *HybridSearch

NewHybridSearch creates a hybrid search engine.

func (*HybridSearch) Search

func (h *HybridSearch) Search(ctx context.Context, query string, opts RecallOpts) ([]*ScoredNode, error)

Search runs hybrid search and returns ranked nodes. 4-path retrieval: BM25 + vector + graph (intent-aware) + temporal recency Based on Hindsight's multi-strategy approach.

type LLMExtractor

type LLMExtractor struct {
	// contains filtered or unexported fields
}

LLMExtractor uses an LLM to extract entities from content. Falls back to regex extraction if LLM is unavailable.

func NewLLMExtractor

func NewLLMExtractor(apiKey, baseURL, model string) *LLMExtractor

NewLLMExtractor creates an LLM-based entity extractor. baseURL: "https://api.openai.com" or any OpenAI-compatible endpoint.

func (*LLMExtractor) Extract

func (e *LLMExtractor) Extract(ctx context.Context, content string) []Entity

Extract returns entities from content using the LLM. Returns regex-extracted entities if LLM call fails.

type MemoryStats

type MemoryStats struct {
	TotalNodes  int
	NodesByType map[string]int
	TotalEdges  int
	LastUpdated time.Time
	TopTopics   []string // top 5 most-connected node subjects
}

MemoryStats holds aggregate statistics about the memory graph.

type Metrics

type Metrics struct {
	Remembers   int64
	Recalls     int64
	Errors      int64
	NodesStored int64
}

Metrics tracks basic engine operation counters.

type NodeHistoryEntry

type NodeHistoryEntry struct {
	Version   int    `json:"version"`
	Content   string `json:"content"`
	ChangedBy string `json:"changed_by"`
	Reason    string `json:"reason"`
	ChangedAt string `json:"changed_at"`
}

NodeHistoryEntry represents one version of a memory node.

type ProactiveContext

type ProactiveContext struct {
	// contains filtered or unexported fields
}

ProactiveContext predicts what context the agent will likely need next by analyzing recent access patterns and graph connectivity.

func NewProactiveContext

func NewProactiveContext(eng *Engine, search *HybridSearch) *ProactiveContext

NewProactiveContext creates a proactive context predictor.

func (*ProactiveContext) Predict

func (p *ProactiveContext) Predict(ctx context.Context, project string, budget int) ([]*storage.Node, error)

Predict returns nodes likely needed in the next session based on: 1. Recently accessed nodes and their neighbors 2. Active tasks and their dependencies 3. High-centrality nodes in the project subgraph

type QueryResult

type QueryResult struct {
	Answer     string          // synthesized answer from retrieved memories
	Sources    []*storage.Node // the memories used to form the answer
	Confidence float64         // 0-1, based on relevance scores of retrieved nodes
}

QueryResult holds the answer to a natural language query.

type RecallOpts

type RecallOpts struct {
	Query   string
	Depth   int
	Limit   int
	Budget  int // max tokens in response (0 = no cap)
	Type    string
	Tier    int
	Project string
}

RecallOpts configures a recall search.

type RecallResult

type RecallResult struct {
	Nodes []*storage.Node
	Edges []*storage.Edge
}

RecallResult holds search results.

type RememberInput

type RememberInput struct {
	Type     string // convention|decision|bug|spec|task|preference
	Content  string
	Summary  string // doubles as short searchable title (Engram Title)
	Scope    string // global|project
	Project  string
	Tier     int
	Tags     string
	Key      string // optional unique key per project (upsert: same key → update, not duplicate)
	TopicKey string // topic-based upsert dedup key (Engram pattern); stored in Tags as "topic:<key>"
	Pinned   bool   // pinned nodes always appear in context output
	Session  string
	Agent    string
	// Optional: explicit edges to create
	Edges []EdgeInput
}

RememberInput is the input for creating a memory node.

type ScoredNode

type ScoredNode struct {
	Node  *storage.Node
	Score float64
}

ScoredNode is a node with a combined relevance score.

func Rerank

func Rerank(ctx context.Context, nodes []*ScoredNode, store storage.Storage) []*ScoredNode

Rerank re-scores nodes combining RRF score, graph centrality, recency, and confidence.

type Status

type Status struct {
	Nodes    int
	Edges    int
	Sessions int
}

Status returns basic stats.

type UserProfile

type UserProfile struct {
	Preferences map[string]string // e.g., "indent": "tabs", "test_framework": "testify"
	Patterns    []string          // observed patterns: "always runs tests after edit"
	UpdatedAt   time.Time
}

UserProfile holds user preferences and observed patterns for a project.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL