memory

package
v0.0.212 Latest Latest
Warning

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

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

Documentation

Index

Constants

View Source
const (
	DefaultSourceMine = "mine"
)

Variables

This section is empty.

Functions

func GetDBPath

func GetDBPath() (string, error)

GetDBPath returns the default memory.db path.

func GetDataDir

func GetDataDir() (string, error)

GetDataDir returns the XDG data directory for term-llm.

func ResolveDBPath

func ResolveDBPath(pathOverride string) (string, error)

ResolveDBPath resolves an optional DB path override.

Types

type Config

type Config struct {
	Path string // Optional DB path override (supports :memory:)
}

Config controls memory store initialization.

type Fragment

type Fragment struct {
	ID          string
	RowID       int64
	Agent       string
	Path        string
	Content     string
	Source      string
	CreatedAt   time.Time
	UpdatedAt   time.Time
	AccessedAt  *time.Time
	AccessCount int
	DecayScore  float64
	Pinned      bool
}

Fragment is a durable memory item extracted from sessions.

type FragmentSource added in v0.0.101

type FragmentSource struct {
	ID        int64
	Agent     string
	Path      string
	SessionID string
	TurnStart int
	TurnEnd   int
	CreatedAt time.Time
}

FragmentSource records a link between a memory fragment (L1) and the raw session turn range (L2) that the fragment was mined from. One fragment can accumulate many sources over time as the miner revisits sessions.

type ImageListOptions added in v0.0.94

type ImageListOptions struct {
	Agent  string
	Limit  int
	Offset int
}

ImageListOptions controls listing of generated images.

type ImageRecord added in v0.0.94

type ImageRecord struct {
	ID         string    `json:"id"`
	Agent      string    `json:"agent"`
	SessionID  string    `json:"session_id"`
	Prompt     string    `json:"prompt"`
	OutputPath string    `json:"output_path"`
	MimeType   string    `json:"mime_type"`
	Provider   string    `json:"provider"`
	Width      int       `json:"width"`
	Height     int       `json:"height"`
	FileSize   int       `json:"file_size"`
	CreatedAt  time.Time `json:"created_at"`
}

ImageRecord is a record of a generated image.

type Insight added in v0.0.105

type Insight struct {
	ID                 int64
	Agent              string
	Content            string
	CompactContent     string // short form for injection; falls back to Content if empty
	Category           string
	TriggerDesc        string
	Confidence         float64
	ReinforcementCount int
	CreatedAt          time.Time
	LastReinforced     time.Time
}

Insight is a generalized behavioral rule extracted from past sessions. Unlike fragments (which store facts), insights store actionable patterns that change how the agent behaves in future similar situations.

type InsightsExpander added in v0.0.105

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

InsightsExpander wraps a Store and exposes a single Expand method for appending behavioral insights to the resolved system prompt. A nil *InsightsExpander is always a safe no-op — callers never need to nil-check before calling.

func NewInsightsExpander added in v0.0.105

func NewInsightsExpander(store *Store, agent string, maxTokens int) *InsightsExpander

NewInsightsExpander returns an expander configured for the given agent. maxTokens is the token budget for the injected block (0 → default 500). Returns nil when store is nil — the nil receiver is safe to call.

func (*InsightsExpander) Expand added in v0.0.105

func (e *InsightsExpander) Expand(ctx context.Context, _ string) string

Expand returns the formatted insight block for the configured agent. Returns "" when disabled, no insights exist, or on any error.

type ListOptions

type ListOptions struct {
	Agent      string
	Since      *time.Time
	Limit      int
	PathFilter string // substring match on path (case-insensitive)
}

ListOptions configures fragment listing.

type MiningState

type MiningState struct {
	SessionID       string
	Agent           string
	LastMinedOffset int
	MinedAt         time.Time
}

MiningState tracks per-session mining progress.

type ScoredFragment added in v0.0.94

type ScoredFragment struct {
	ID          string    `json:"id"`
	Agent       string    `json:"agent"`
	Path        string    `json:"path"`
	Content     string    `json:"-"`
	Source      string    `json:"-"`
	CreatedAt   time.Time `json:"-"`
	UpdatedAt   time.Time `json:"-"`
	AccessedAt  *time.Time
	AccessCount int       `json:"-"`
	DecayScore  float64   `json:"-"`
	Pinned      bool      `json:"-"`
	Snippet     string    `json:"snippet"`
	Score       float64   `json:"score"`
	Vector      []float64 `json:"-"`
}

ScoredFragment is a fragment paired with a relevance score.

type SearchResult

type SearchResult struct {
	Agent   string  `json:"agent"`
	Path    string  `json:"path"`
	Snippet string  `json:"snippet"`
	Score   float64 `json:"score"`
}

SearchResult is a BM25 result from FTS.

type Store

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

Store persists memory fragments and mining state.

func NewStore

func NewStore(cfg Config) (*Store, error)

NewStore opens memory.db and initializes schema.

func (*Store) AddFragmentSource added in v0.0.101

func (s *Store) AddFragmentSource(ctx context.Context, agent, path, sessionID string, turnStart, turnEnd int) error

AddFragmentSource records that the fragment at (agent, path) was derived from messages [turnStart, turnEnd) of sessionID. Duplicate rows (same agent, path, session, and turn range) are silently ignored.

func (*Store) BumpAccess added in v0.0.94

func (s *Store) BumpAccess(ctx context.Context, fragmentID string) error

BumpAccess marks a fragment as recently accessed, increments access_count, and gives decay_score a small recency boost.

func (*Store) Close

func (s *Store) Close() error

Close closes the underlying DB.

func (*Store) CountGCCandidates added in v0.0.94

func (s *Store) CountGCCandidates(ctx context.Context, agent string) (int, error)

CountGCCandidates counts fragments eligible for GC.

func (*Store) CreateFragment

func (s *Store) CreateFragment(ctx context.Context, f *Fragment) error

CreateFragment inserts a new fragment and syncs FTS explicitly.

func (*Store) CreateInsight added in v0.0.105

func (s *Store) CreateInsight(ctx context.Context, ins *Insight) error

CreateInsight inserts a new insight and syncs the FTS index.

func (*Store) DecayInsights added in v0.0.105

func (s *Store) DecayInsights(ctx context.Context, agent string, halfLifeDays float64) (int, error)

DecayInsights reduces confidence for insights that haven't been reinforced recently, using an exponential half-life model identical to fragment decay. For each insight, the new confidence is:

new = current * 2^(-days_since_reinforced / halfLifeDays)

Returns the number of insights updated.

func (*Store) DeleteFragment

func (s *Store) DeleteFragment(ctx context.Context, agent, path string) (deleted bool, err error)

DeleteFragment removes a fragment and syncs FTS. Returns deleted=false when no matching fragment exists.

func (*Store) DeleteFragmentByRowID added in v0.0.97

func (s *Store) DeleteFragmentByRowID(ctx context.Context, rowID int64) (deleted bool, err error)

DeleteFragmentByRowID removes a fragment by its SQLite rowid. Returns deleted=false if no fragment with that rowid exists.

func (*Store) DeleteInsight added in v0.0.105

func (s *Store) DeleteInsight(ctx context.Context, id int64) (bool, error)

DeleteInsight removes an insight and its FTS entry.

func (*Store) ExpandInsights added in v0.0.105

func (s *Store) ExpandInsights(ctx context.Context, agent, _ string, maxTokens int) (string, error)

ExpandInsights returns all insights for the agent sorted by confidence, formatted as a compact block ready for injection into conversation context. maxTokens is a rough token budget (approximated at 4 chars/token). Returns an empty string when the bank is empty.

No search/filtering is applied: insight banks are small and curated, so returning all of them (within the token cap) is more correct than trying to match them against the user's first message via BM25 or embeddings.

func (*Store) FindFragmentsByPath

func (s *Store) FindFragmentsByPath(ctx context.Context, path string) ([]Fragment, error)

FindFragmentsByPath fetches fragments for a path across all agents.

func (*Store) FragmentCountsByAgent

func (s *Store) FragmentCountsByAgent(ctx context.Context) (map[string]int, error)

FragmentCountsByAgent returns count(fragment) grouped by agent.

func (*Store) GCFragments added in v0.0.94

func (s *Store) GCFragments(ctx context.Context, agent string) (int, error)

GCFragments deletes decayed, non-pinned fragments and keeps FTS in sync.

func (*Store) GCInsights added in v0.0.105

func (s *Store) GCInsights(ctx context.Context, agent string, minConfidence float64) (int, error)

GCInsights deletes insights whose confidence has fallen below minConfidence. This is typically called after DecayInsights to prune stale entries. Returns the number of insights deleted.

func (*Store) GetEmbedding added in v0.0.94

func (s *Store) GetEmbedding(ctx context.Context, fragmentID, provider, model string) ([]float64, error)

GetEmbedding fetches a stored embedding vector for a fragment+provider+model.

func (*Store) GetEmbeddingsByIDs added in v0.0.94

func (s *Store) GetEmbeddingsByIDs(ctx context.Context, fragmentIDs []string, provider, model string) (map[string][]float64, error)

func (*Store) GetFragment

func (s *Store) GetFragment(ctx context.Context, agent, path string) (*Fragment, error)

GetFragment fetches a fragment by (agent,path).

func (*Store) GetFragmentByRowID added in v0.0.96

func (s *Store) GetFragmentByRowID(ctx context.Context, rowID int64) (*Fragment, error)

GetFragmentByRowID fetches a fragment by its SQLite rowid.

func (*Store) GetFragmentSources added in v0.0.101

func (s *Store) GetFragmentSources(ctx context.Context, agent, path string) ([]FragmentSource, error)

GetFragmentSources returns all source records for a given (agent, path) fragment, ordered oldest first.

func (*Store) GetFragmentsNeedingEmbedding added in v0.0.94

func (s *Store) GetFragmentsNeedingEmbedding(ctx context.Context, agent, provider, model string) ([]Fragment, error)

GetFragmentsNeedingEmbedding returns fragments missing an embedding row for provider+model.

func (*Store) GetInsightByID added in v0.0.105

func (s *Store) GetInsightByID(ctx context.Context, id int64) (*Insight, error)

GetInsightByID returns a single insight by its row ID.

func (*Store) GetMeta added in v0.0.94

func (s *Store) GetMeta(ctx context.Context, key string) (string, error)

GetMeta returns a value from memory_meta. Missing keys return "", nil.

func (*Store) GetSourcesForSession added in v0.0.101

func (s *Store) GetSourcesForSession(ctx context.Context, sessionID string) ([]FragmentSource, error)

GetSourcesForSession returns all fragment sources that were derived from a given session, ordered by path. Useful for auditing what a session produced.

func (*Store) GetState

func (s *Store) GetState(ctx context.Context, sessionID string) (*MiningState, error)

GetState returns mining state for a session.

func (*Store) InsightMinedAt added in v0.0.105

func (s *Store) InsightMinedAt(ctx context.Context, sessionID string) (time.Time, error)

InsightMinedAt returns the time a session's insights were last extracted, or (time.Time{}, nil) if the session has never been insight-mined.

func (*Store) LastMinedByAgent

func (s *Store) LastMinedByAgent(ctx context.Context) (map[string]time.Time, error)

LastMinedByAgent returns MAX(mined_at) grouped by agent.

SQLite aggregate functions like MAX() return the underlying value as a plain string, bypassing the driver's column-type inference that makes direct column scans into time.Time work. We therefore scan as a string and parse manually, accepting both RFC3339 (current format written by UpsertState) and the legacy Go time.String() format that older rows may contain.

func (*Store) ListAgents added in v0.0.94

func (s *Store) ListAgents(ctx context.Context) ([]string, error)

ListAgents returns distinct agent names that have stored fragments.

func (*Store) ListFragmentPaths added in v0.0.195

func (s *Store) ListFragmentPaths(ctx context.Context, agent, prefix string, limit int) ([]string, error)

ListFragmentPaths returns only fragment paths for lightweight listings. Results preserve ListFragments' newest-first ordering, but avoid reading large content bodies when callers only need path names (for example, mining tools).

func (*Store) ListFragments

func (s *Store) ListFragments(ctx context.Context, opts ListOptions) ([]Fragment, error)

ListFragments returns fragments sorted by created_at descending (most recently learned first). updated_at is only bumped when content actually changes, so ordering by it would give misleading results when many fragments happen to be updated in the same batch. RowID is populated on each returned Fragment.

func (*Store) ListImageAgents added in v0.0.94

func (s *Store) ListImageAgents(ctx context.Context) ([]string, error)

ListImageAgents returns distinct agent names for generated images.

func (*Store) ListImages added in v0.0.94

func (s *Store) ListImages(ctx context.Context, opts ImageListOptions) ([]ImageRecord, error)

ListImages returns generated images ordered by creation time (newest first).

func (*Store) ListImagesSince added in v0.0.94

func (s *Store) ListImagesSince(ctx context.Context, agent string, since time.Time) ([]ImageRecord, error)

ListImagesSince returns generated images for an agent created after the given time.

func (*Store) ListInsights added in v0.0.105

func (s *Store) ListInsights(ctx context.Context, agent string, limit int) ([]*Insight, error)

ListInsights returns insights for an agent, newest first.

func (*Store) MarkInsightMined added in v0.0.105

func (s *Store) MarkInsightMined(ctx context.Context, sessionID, agent string) error

MarkInsightMined records that insight extraction has run for a session.

func (*Store) RecalcDecayScores added in v0.0.94

func (s *Store) RecalcDecayScores(ctx context.Context, agent string, halfLifeDays float64) (int, error)

RecalcDecayScores recalculates decay_score for non-pinned fragments. halfLifeDays defaults to 30 when <= 0.

func (*Store) RecordImage added in v0.0.94

func (s *Store) RecordImage(ctx context.Context, r *ImageRecord) error

RecordImage inserts a generated image record into the store. Non-fatal in callers: errors do not stop image generation.

func (*Store) ReinforceInsight added in v0.0.105

func (s *Store) ReinforceInsight(ctx context.Context, id int64) error

ReinforceInsight bumps the reinforcement count and nudges confidence upward using a logarithmic schedule (diminishing returns after the first few observations).

func (*Store) SearchBM25 added in v0.0.94

func (s *Store) SearchBM25(ctx context.Context, query string, limit int, agent string) ([]ScoredFragment, error)

SearchBM25 performs BM25 search over FTS5 and returns fragment details.

func (*Store) SearchFragments

func (s *Store) SearchFragments(ctx context.Context, query string, limit int, agent string) ([]SearchResult, error)

SearchFragments performs BM25 search over FTS5.

func (*Store) SearchImages added in v0.0.94

func (s *Store) SearchImages(ctx context.Context, query, agent string, limit int) ([]ImageRecord, error)

SearchImages searches generated images by prompt/path using FTS5.

func (*Store) SearchInsights added in v0.0.105

func (s *Store) SearchInsights(ctx context.Context, agent, query string, limit int) ([]*Insight, error)

SearchInsights finds insights via BM25 full-text search. Used for deduplication during extraction (checking if a newly mined insight already exists), not for injection — ExpandInsights returns all insights sorted by confidence instead.

func (*Store) SetMeta added in v0.0.94

func (s *Store) SetMeta(ctx context.Context, key, value string) error

SetMeta upserts a key/value pair in memory_meta.

func (*Store) UpdateFragment

func (s *Store) UpdateFragment(ctx context.Context, agent, path, content string) (updated bool, err error)

UpdateFragment updates content for an existing (agent,path) fragment and syncs FTS. Returns updated=false when no matching fragment exists or content is identical (no-op). updated_at is only bumped when content actually changes.

func (*Store) UpdateFragmentByRowID added in v0.0.97

func (s *Store) UpdateFragmentByRowID(ctx context.Context, rowID int64, content string) (updated bool, err error)

UpdateFragmentByRowID updates a fragment looked up by its SQLite rowid. Returns updated=false if no fragment with that rowid exists, or content is unchanged.

func (*Store) UpdateInsight added in v0.0.105

func (s *Store) UpdateInsight(ctx context.Context, id int64, content, compact string) error

UpdateInsight replaces the content (and optionally compact_content) of an insight and resets FTS. Pass compact="" to leave the compact form unchanged.

func (*Store) UpsertEmbedding added in v0.0.94

func (s *Store) UpsertEmbedding(ctx context.Context, fragmentID, provider, model string, dims int, vec []float64) error

UpsertEmbedding inserts or updates an embedding vector for a fragment.

func (*Store) UpsertState

func (s *Store) UpsertState(ctx context.Context, st *MiningState) error

UpsertState inserts or updates mining state.

func (*Store) VectorSearch added in v0.0.94

func (s *Store) VectorSearch(ctx context.Context, agent, provider, model string, queryVec []float64, limit int) ([]ScoredFragment, error)

VectorSearch performs a full cosine similarity scan over embeddings.

Jump to

Keyboard shortcuts

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