memory

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Jun 1, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package memory provides salience-driven graph-backed episodic memory. Entities (mutable) represent current state. Memories (immutable/append-only) represent historical record. The memory_entities junction table bridges graph and episodic memory (many-to-many).

Index

Constants

View Source
const (
	DefaultEntityProfileBudget = 200
	DefaultGraphBudget         = 300
	DefaultMaxTokens           = 2000
)

Default budget allocations.

View Source
const (
	DefaultDecayRate          = 0.995
	DefaultBoostAmount        = 0.05
	DefaultMinSalience        = 0.1
	DefaultSalience           = 0.5
	DefaultConsolidationDecay = 0.5
)

Salience engine defaults.

View Source
const (
	MemoryTypeFact          = "fact"
	MemoryTypePreference    = "preference"
	MemoryTypeDecision      = "decision"
	MemoryTypeExperience    = "experience"
	MemoryTypeFailure       = "failure"
	MemoryTypeObservation   = "observation"
	MemoryTypeConsolidation = "consolidation"
)

Valid memory types.

View Source
const (
	LineageSupersedes   = "SUPERSEDES"
	LineageConsolidates = "CONSOLIDATES"
)

Valid lineage relation types.

View Source
const (
	RoleAbout    = "about"
	RoleBy       = "by"
	RoleFor      = "for"
	RoleMentions = "mentions"
)

Valid memory entity roles.

Variables

This section is empty.

Functions

func BoostSalience

func BoostSalience(current, boost float64) float64

BoostSalience increases salience by the boost amount, capped at 1.0.

func CombineScores

func CombineScores(salience, relevance float64) float64

CombineScores combines salience and relevance into a final score. Uses multiplicative combination: combined = salience * relevance.

func ComputeSalience

func ComputeSalience(base float64, lastAccessOrCreation time.Time, now time.Time, decayRate float64) float64

ComputeSalience applies time-based decay to a base salience value. Formula: S_current = S_base * decay_rate^(days_since_last_access_or_creation)

func CosineSimilarity

func CosineSimilarity(a, b []float32) float32

CosineSimilarity computes the cosine similarity between two vectors. Returns a value in [-1, 1] where 1 means identical direction.

func EdgeToProto

func EdgeToProto(e *Edge) *loomv1.GraphEdge

EdgeToProto converts a domain Edge to its proto representation.

func EntityRecallToProto

func EntityRecallToProto(er *EntityRecall) *loomv1.EntityRecall

EntityRecallToProto converts a domain EntityRecall to its proto representation.

func EntityToProto

func EntityToProto(e *Entity) *loomv1.GraphEntity

EntityToProto converts a domain Entity to its proto representation.

func GraphStatsToProto

func GraphStatsToProto(gs *GraphStats) *loomv1.GraphStats

GraphStatsToProto converts a domain GraphStats to its proto representation.

func LineageToProto

func LineageToProto(l *MemoryLineage) *loomv1.MemoryLineage

LineageToProto converts a domain MemoryLineage to its proto representation.

func MemoryToProto

func MemoryToProto(m *Memory) *loomv1.GraphMemory

MemoryToProto converts a domain Memory to its proto representation.

func ScoredMemoryToProto

func ScoredMemoryToProto(sm *ScoredMemory) *loomv1.ScoredMemory

ScoredMemoryToProto converts a domain ScoredMemory to its proto representation.

Types

type BudgetConfig

type BudgetConfig struct {
	// MaxTokens is the total token budget.
	MaxTokens int
	// EntityProfileBudget is the budget reserved for entity profile (phase 1).
	EntityProfileBudget int
	// GraphBudget is the budget reserved for graph neighborhood (phase 2).
	GraphBudget int
}

BudgetConfig configures the phased token budget allocation for ContextFor queries.

func DefaultBudgetConfig

func DefaultBudgetConfig(maxTokens int) BudgetConfig

DefaultBudgetConfig returns a config with spec defaults for a given total budget.

func (BudgetConfig) MemoryBudget

func (bc BudgetConfig) MemoryBudget() int

MemoryBudget returns the remaining budget available for memories after entity profile and graph neighborhood are allocated.

type ContextForOpts

type ContextForOpts struct {
	AgentID    string
	EntityName string
	Topic      string // FTS query for relevant memories
	MaxTokens  int    // total budget
}

ContextForOpts configures a composite context query.

type Edge

type Edge struct {
	ID             string
	AgentID        string
	SourceID       string
	TargetID       string
	Relation       string // USES, FOLLOWS, KNOWS_ABOUT, PARENT_OF, WORKS_AT, etc.
	PropertiesJSON string
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

Edge is a mutable directed relationship between two entities.

func EdgeFromProto

func EdgeFromProto(pb *loomv1.GraphEdge) *Edge

EdgeFromProto converts a proto GraphEdge to a domain Edge.

type Embedder

type Embedder interface {
	// Embed returns a vector embedding for the given text.
	Embed(ctx context.Context, text string) ([]float32, error)

	// EmbedBatch returns embeddings for multiple texts. Implementations
	// should batch API calls where possible for efficiency.
	EmbedBatch(ctx context.Context, texts []string) ([][]float32, error)

	// Dimensions returns the dimensionality of embeddings produced.
	Dimensions() int

	// Model returns the model identifier. Stored with each embedding so that
	// model changes don't corrupt recall (incompatible vector spaces).
	Model() string
}

Embedder produces vector embeddings from text. Implementations may use OpenAI, local models, or any provider that returns fixed-dimension float32 vectors.

type Entity

type Entity struct {
	ID             string
	AgentID        string
	Name           string
	EntityType     string // person, tool, pattern, concept, project, device, etc.
	PropertiesJSON string
	Owner          string
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

Entity is a mutable node representing current state in the knowledge graph.

func EntityFromProto

func EntityFromProto(pb *loomv1.GraphEntity) *Entity

EntityFromProto converts a proto GraphEntity to a domain Entity.

type EntityIDRole

type EntityIDRole struct {
	ID   string
	Role string // RoleAbout, RoleMentions, etc.
}

EntityIDRole pairs an entity ID with its role in a memory. Used by linkEntitiesTx to store the correct role per entity.

type EntityRecall

type EntityRecall struct {
	Entity          *Entity
	Memories        []ScoredMemory
	EdgesOut        []*Edge
	EdgesIn         []*Edge
	EntityNames     map[string]string // ID -> name lookup for edge endpoints
	TotalTokensUsed int
	TotalCandidates int
}

EntityRecall is the composite result of a ContextFor query.

func EntityRecallFromProto

func EntityRecallFromProto(pb *loomv1.EntityRecall) *EntityRecall

EntityRecallFromProto converts a proto EntityRecall to a domain EntityRecall.

func (*EntityRecall) Format

func (er *EntityRecall) Format() string

Format renders the EntityRecall as a string for injection into LLM context.

type GraphMemoryStore

type GraphMemoryStore interface {
	// Entity CRUD (mutable)
	CreateEntity(ctx context.Context, entity *Entity) (*Entity, error)
	GetEntity(ctx context.Context, agentID, name string) (*Entity, error)
	UpdateEntity(ctx context.Context, entity *Entity) (*Entity, error)
	ListEntities(ctx context.Context, agentID, entityType string, limit, offset int) ([]*Entity, int, error)
	SearchEntities(ctx context.Context, agentID, query string, limit int) ([]*Entity, error)
	DeleteEntity(ctx context.Context, agentID, name string) error

	// Edge CRUD (mutable, UNIQUE on source+target+relation)
	Relate(ctx context.Context, edge *Edge) (*Edge, error) // upsert
	Unrelate(ctx context.Context, sourceID, targetID, relation string) error
	Neighbors(ctx context.Context, entityID string, relation string, direction string, depth int) ([]*Edge, error)
	ListEdgesFrom(ctx context.Context, entityID string) ([]*Edge, error)
	ListEdgesTo(ctx context.Context, entityID string) ([]*Edge, error)

	// Memory (append-only, immutable content)
	Remember(ctx context.Context, mem *Memory) (*Memory, error)
	GetMemory(ctx context.Context, agentID, memoryID string) (*Memory, error)
	Recall(ctx context.Context, opts RecallOpts) ([]*Memory, error)
	Forget(ctx context.Context, memoryID string) error                                  // soft-delete: set expires_at
	Supersede(ctx context.Context, oldMemoryID string, newMem *Memory) (*Memory, error) // creates SUPERSEDES lineage
	Consolidate(ctx context.Context, memoryIDs []string, consolidated *Memory) (*Memory, error)
	GetLineage(ctx context.Context, memoryID string) ([]*MemoryLineage, error)

	// Access tracking (the only allowed mutation on memories)
	TouchMemories(ctx context.Context, memoryIDs []string) error

	// Salience management
	DecayAll(ctx context.Context, agentID string, decayFactor float64) error

	// Composite query
	ContextFor(ctx context.Context, opts ContextForOpts) (*EntityRecall, error)

	// Vector similarity search (returns memories ordered by cosine similarity).
	// Implementations: SQLite uses brute-force in Go; PostgreSQL uses pgvector HNSW.
	// Returns nil, nil if embeddings are not enabled for this store.
	VectorRecall(ctx context.Context, opts VectorRecallOpts) ([]*Memory, error)

	// Stats
	GetStats(ctx context.Context, agentID string) (*GraphStats, error)

	Close() error
}

GraphMemoryStore defines the storage interface for graph-backed episodic memory. Implementations exist for SQLite and PostgreSQL.

type GraphStats

type GraphStats struct {
	EntityCount       int
	EdgeCount         int
	MemoryCount       int
	ActiveMemoryCount int
	TotalMemoryTokens int
	MemoriesByType    map[string]int
}

GraphStats provides entity/memory/token counts.

func GraphStatsFromProto

func GraphStatsFromProto(pb *loomv1.GraphStats) *GraphStats

GraphStatsFromProto converts a proto GraphStats to a domain GraphStats.

type Memory

type Memory struct {
	ID                string
	AgentID           string
	Content           string
	Summary           string
	MemoryType        string // fact, preference, decision, experience, failure, observation, consolidation
	Source            string // conversation, observation, manual, agent
	SourceID          string
	Owner             string
	MemoryAgentID     string
	Tags              []string
	Salience          float64
	TokenCount        int
	SummaryTokenCount int
	AccessCount       int
	EntityIDs         []string
	EntityRoles       []EntityIDRole // takes precedence over EntityIDs when present
	PropertiesJSON    string
	Embedding         []float32 // vector embedding for semantic search (nil = not embedded)
	EmbeddingModel    string    // model that produced the embedding (for compatibility checks)
	// EventDate is the absolute ISO date (YYYY-MM-DD) when the fact this
	// memory describes occurred, computed by the extractor from the session
	// date and the user's relative time phrase. Empty when the memory has no
	// temporal dimension, or when the extractor could not resolve an absolute
	// date (see EventDateConfidence).
	EventDate string
	// EventDateConfidence is "exact", "approximate", "ambiguous", or empty.
	// "ambiguous" signals the extractor saw a time cue but deliberately chose
	// not to fabricate a date; consumers should treat the memory as undated.
	EventDateConfidence string
	CreatedAt           time.Time
	AccessedAt          *time.Time // nil = never accessed
	ExpiresAt           *time.Time // nil = never expires
	IsSuperseded        bool
}

Memory is IMMUTABLE once created. Only AccessedAt, AccessCount, Salience, and ExpiresAt may be mutated (via specific engine operations).

func MemoryFromProto

func MemoryFromProto(pb *loomv1.GraphMemory) *Memory

MemoryFromProto converts a proto GraphMemory to a domain Memory.

type MemoryLineage

type MemoryLineage struct {
	NewMemoryID  string
	OldMemoryID  string
	RelationType string // SUPERSEDES or CONSOLIDATES
	CreatedAt    time.Time
}

MemoryLineage tracks SUPERSEDES and CONSOLIDATES chains.

func LineageFromProto

func LineageFromProto(pb *loomv1.MemoryLineage) *MemoryLineage

LineageFromProto converts a proto MemoryLineage to a domain MemoryLineage.

type RecallOpts

type RecallOpts struct {
	AgentID     string
	Query       string   // FTS search query
	MemoryType  string   // filter (empty = all)
	EntityIDs   []string // scope to entities (empty = all)
	Tags        []string // filter by tags
	MinSalience float64
	MaxTokens   int // 0 = no limit
	Limit       int // max results
}

RecallOpts configures a memory recall query.

type SalienceConfig

type SalienceConfig struct {
	DecayRate          float64
	BoostAmount        float64
	MinSalience        float64
	ConsolidationDecay float64
}

SalienceConfig holds parameters for salience computation.

func DefaultSalienceConfig

func DefaultSalienceConfig() SalienceConfig

DefaultSalienceConfig returns a config with spec defaults.

type ScoredMemory

type ScoredMemory struct {
	Memory           *Memory
	ComputedSalience float64
	RelevanceScore   float64
	CombinedScore    float64
	UsedSummary      bool // true if summary used instead of full content
}

ScoredMemory is a memory with computed ranking scores.

func AllocateMemoryBudget

func AllocateMemoryBudget(candidates []ScoredMemory, remainingTokens int) ([]ScoredMemory, int)

AllocateMemoryBudget takes sorted candidates (highest salience first) and packs them into the remaining token budget with graceful degradation:

  • If full content fits -> include content
  • Elif summary fits -> include summary (set UsedSummary=true)
  • Else -> skip

Returns the packed memories and total tokens consumed.

func RankBySalience

func RankBySalience(candidates []*Memory, config SalienceConfig, now time.Time) []ScoredMemory

RankBySalience computes salience for each memory, filters by threshold, and sorts descending.

func ScoredMemoryFromProto

func ScoredMemoryFromProto(pb *loomv1.ScoredMemory) *ScoredMemory

ScoredMemoryFromProto converts a proto ScoredMemory to a domain ScoredMemory.

type TokenCounter

type TokenCounter interface {
	CountTokens(text string) int
}

TokenCounter counts tokens. Satisfied by *agent.TokenCounter.

type VectorRecallOpts

type VectorRecallOpts struct {
	AgentID   string
	Embedding []float32 // query vector
	Model     string    // only match embeddings from this model (required)
	Limit     int       // max results (default: 20)
	Threshold float32   // minimum cosine similarity (default: 0.0)
}

VectorRecallOpts configures a vector similarity search.

Jump to

Keyboard shortcuts

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