Documentation
¶
Overview ¶
Package agentmem is a SQL-backed agent memory store.
It mirrors the semantics of agent-go's pkg/store FileMemoryStore — typed memories (fact / skill / pattern / context / preference / observation), Hindsight fields (evidence / confidence / valid_from-to / superseded_by / conflicting / revisions / archived), bank configuration, mental models, and OpenClaw-style context slots — but persists everything in CortexDB's SQLite file rather than a tree of Markdown files.
The package does NOT require an embedder. Search is based on FTS5 (the trigram tokenizer when available, unicode61 as fallback) re-ranked with importance and exponential time decay.
Quick Start ¶
cdb, _ := cortexdb.Open(cortexdb.DefaultConfig("memory.db"))
defer cdb.Close()
store, _ := agentmem.New(cdb)
_ = store.Save(ctx, &agentmem.Memory{
Scope: agentmem.Scope{Type: agentmem.ScopeUser, ID: "alice"},
Type: agentmem.TypeFact,
Content: "Apollo ships on Friday.",
Importance: 0.8,
Tags: []string{"apollo", "deadline"},
})
hits, _ := store.SearchByText(ctx, "apollo deadline", agentmem.SearchOptions{TopK: 5})
for _, h := range hits { _ = h.Memory }
Reflection ¶
Reflect plugs in any Reflector implementation (LLM-backed or deterministic):
type myReflector struct{}
func (myReflector) Consolidate(ctx context.Context, facts, existing []*agentmem.Memory) ([]agentmem.Observation, error) {
// produce one or more observations citing fact ids as evidence
}
res, _ := store.Reflect(ctx, scope, myReflector{})
Context Slots ¶
Context slots replace agent-go's MEMORY.md/AGENTS.md/SOUL.md/TOOLS.md/HEARTBEAT.md fixed files. They live in agentmem_context_slots and can be assembled into a single string with BuildContextString.
Index ¶
- Variables
- func BankID(scope Scope) string
- func IsStale(m *Memory) bool
- type BankConfig
- type ContextSlot
- type EntrypointOptions
- type Memory
- type MentalModel
- type Observation
- type ReflectResult
- type Reflector
- type Revision
- type Scope
- type ScopeType
- type ScoredMemory
- type SearchOptions
- type SourceType
- type Store
- func (s *Store) AddMentalModel(ctx context.Context, m *MentalModel) error
- func (s *Store) AddRevision(ctx context.Context, id, by, summary string) error
- func (s *Store) AppendContext(ctx context.Context, scope Scope, slot ContextSlot, content string) error
- func (s *Store) Archive(ctx context.Context, id, reason string) error
- func (s *Store) BuildContextString(ctx context.Context, scope Scope, order []ContextSlot) (string, error)
- func (s *Store) BuildEntrypoint(ctx context.Context, scope Scope, opts EntrypointOptions) (string, error)
- func (s *Store) Clear(ctx context.Context) error
- func (s *Store) ConfigureBank(ctx context.Context, scope Scope, cfg *BankConfig) error
- func (s *Store) Delete(ctx context.Context, id string) error
- func (s *Store) DeleteContext(ctx context.Context, scope Scope, slot ContextSlot) error
- func (s *Store) DeleteMentalModel(ctx context.Context, id string) error
- func (s *Store) Get(ctx context.Context, id string) (*Memory, error)
- func (s *Store) GetBankConfig(ctx context.Context, scope Scope) (*BankConfig, error)
- func (s *Store) GetByType(ctx context.Context, t Type, limit int) ([]*Memory, error)
- func (s *Store) GetContext(ctx context.Context, scope Scope, slot ContextSlot) (string, error)
- func (s *Store) IncrementAccess(ctx context.Context, id string) error
- func (s *Store) List(ctx context.Context, limit, offset int) ([]*Memory, int, error)
- func (s *Store) ListByScope(ctx context.Context, scope Scope, limit int) ([]*Memory, error)
- func (s *Store) ListMentalModels(ctx context.Context) ([]MentalModel, error)
- func (s *Store) MarkStale(ctx context.Context, id, supersededBy string) error
- func (s *Store) Parent() *cortexdb.DB
- func (s *Store) Reflect(ctx context.Context, scope Scope, r Reflector) (*ReflectResult, error)
- func (s *Store) Save(ctx context.Context, m *Memory) error
- func (s *Store) SearchByScope(ctx context.Context, query string, scopes []Scope, opts SearchOptions) ([]ScoredMemory, error)
- func (s *Store) SearchByText(ctx context.Context, query string, opts SearchOptions) ([]ScoredMemory, error)
- func (s *Store) SearchByType(ctx context.Context, t Type, limit int) ([]*Memory, error)
- func (s *Store) SetContext(ctx context.Context, scope Scope, slot ContextSlot, content string) error
- func (s *Store) Unarchive(ctx context.Context, id string) error
- func (s *Store) UsesFallbackTokenizer() bool
- type Type
Constants ¶
This section is empty.
Variables ¶
var DefaultContextOrder = []ContextSlot{SlotSoul, SlotAgents, SlotTools, SlotMemory, SlotHeartbeat}
DefaultContextOrder is the order BuildContextString uses by default.
var ErrNotFound = errors.New("agentmem: memory not found")
ErrNotFound is returned when a memory id has no row.
Functions ¶
Types ¶
type BankConfig ¶
type BankConfig struct {
Mission string `json:"mission,omitempty"`
Directives []string `json:"directives,omitempty"`
Skepticism int `json:"skepticism,omitempty"`
Literalism int `json:"literalism,omitempty"`
Empathy int `json:"empathy,omitempty"`
}
BankConfig captures the disposition of a memory bank, mirroring agent-go's MemoryBankConfig.
type ContextSlot ¶
type ContextSlot string
ContextSlot names a fixed system-context channel (OpenClaw style).
const ( SlotSoul ContextSlot = "SOUL" SlotAgents ContextSlot = "AGENTS" SlotTools ContextSlot = "TOOLS" SlotMemory ContextSlot = "MEMORY" SlotHeartbeat ContextSlot = "HEARTBEAT" )
type EntrypointOptions ¶
type EntrypointOptions struct {
TopN int
IncludeArchived bool
IncludeStale bool
Title string // optional heading; defaults to "Memory Entrypoint"
}
EntrypointOptions controls BuildEntrypoint.
type Memory ¶
type Memory struct {
ID string `json:"id"`
Scope Scope `json:"scope"`
Type Type `json:"type"`
Content string `json:"content"`
Importance float64 `json:"importance"`
Tags []string `json:"tags,omitempty"`
Keywords []string `json:"keywords,omitempty"`
SourceType SourceType `json:"source_type,omitempty"`
Confidence float64 `json:"confidence,omitempty"`
EvidenceIDs []string `json:"evidence_ids,omitempty"`
ValidFrom time.Time `json:"valid_from,omitempty"`
ValidTo *time.Time `json:"valid_to,omitempty"`
SupersededBy string `json:"superseded_by,omitempty"`
Conflicting bool `json:"conflicting,omitempty"`
Archived bool `json:"archived,omitempty"`
ArchivedAt *time.Time `json:"archived_at,omitempty"`
ArchiveReason string `json:"archive_reason,omitempty"`
AccessCount int `json:"access_count"`
LastAccessed time.Time `json:"last_accessed,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
RevisionHistory []Revision `json:"revision_history,omitempty"`
}
Memory is the canonical agentmem record.
type MentalModel ¶
type MentalModel struct {
ID string `json:"id"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Content string `json:"content"`
Tags []string `json:"tags,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
}
MentalModel is a curated rule or summary kept alongside the bank.
type Observation ¶
type Observation struct {
Content string
Confidence float64
EvidenceIDs []string
Conflicting bool
UpdateObsID string // when set, the existing observation with this id is marked stale
}
Observation is the result of one consolidation step.
type ReflectResult ¶
type ReflectResult struct {
Created int `json:"created"`
Updated int `json:"updated"`
Reviewed int `json:"reviewed"`
NewIDs []string `json:"new_ids,omitempty"`
Note string `json:"note,omitempty"`
}
ReflectResult summarises a Reflect run.
type Reflector ¶
type Reflector interface {
Consolidate(ctx context.Context, facts []*Memory, existing []*Memory) ([]Observation, error)
}
Reflector is the LLM-dependent extension point for consolidating raw facts into observations. It is the agentmem analogue of agent-go's Reflect prompt.
Implementations receive only the candidate facts (already filtered to active, not-yet-evidenced records) and any existing observations in the same scope. They must return one or more Observation rows; agentmem will persist them and optionally mark superseded observations stale.
type Revision ¶
type Revision struct {
At time.Time `json:"at"`
By string `json:"by,omitempty"`
Summary string `json:"summary,omitempty"`
}
Revision is a single audit entry recording a change to a memory.
type ScoredMemory ¶
ScoredMemory is a memory paired with a relevance score.
type SearchOptions ¶
type SearchOptions struct {
TopK int
MinScore float64
IncludeArchived bool
IncludeStale bool // include rows whose ValidTo is set or SupersededBy non-empty
Type Type // optional type filter
BankIDs []string // pre-resolved bank ids (used by SearchByScope)
}
SearchOptions controls SearchByText/SearchByScope behavior.
type SourceType ¶
type SourceType string
SourceType records how a memory was created.
const ( SourceUserInput SourceType = "user_input" SourceInferred SourceType = "inferred" SourceConsolidated SourceType = "consolidated" )
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store provides a SQL-backed agent memory layer mirroring agent-go's FileMemoryStore semantics (typed memories, Hindsight fields, banks, mental models, context slots) without requiring an embedder.
func (*Store) AddMentalModel ¶
func (s *Store) AddMentalModel(ctx context.Context, m *MentalModel) error
AddMentalModel inserts or updates a curated rule.
func (*Store) AddRevision ¶
AddRevision appends a revision entry to a memory's history.
func (*Store) AppendContext ¶
func (s *Store) AppendContext(ctx context.Context, scope Scope, slot ContextSlot, content string) error
AppendContext appends content to a slot, creating it if missing. A newline separator is inserted between the existing content and the new section.
func (*Store) Archive ¶
Archive flags a memory as archived (excluded from default search) and records the reason.
func (*Store) BuildContextString ¶
func (s *Store) BuildContextString(ctx context.Context, scope Scope, order []ContextSlot) (string, error)
BuildContextString concatenates the slots for a scope in the given order (or DefaultContextOrder when nil), emitting `# <SLOT>` headings between non-empty sections. Empty/missing slots are skipped silently.
func (*Store) BuildEntrypoint ¶
func (s *Store) BuildEntrypoint(ctx context.Context, scope Scope, opts EntrypointOptions) (string, error)
BuildEntrypoint renders a Markdown summary of the top-N memories for a scope, ranked by importance (then recency). This replaces agent-go's auto-generated MEMORY.md entrypoint with an in-memory string.
func (*Store) Clear ¶
Clear removes all memories (and side tables) but preserves bank config / mental models / context slots, mirroring agent-go behavior.
func (*Store) ConfigureBank ¶
ConfigureBank stores the disposition for a memory bank (per scope).
func (*Store) DeleteContext ¶
DeleteContext removes a slot.
func (*Store) DeleteMentalModel ¶
DeleteMentalModel removes a rule by id.
func (*Store) GetBankConfig ¶
GetBankConfig returns the bank's stored disposition. Returns ErrNotFound when the bank has not been configured yet.
func (*Store) GetContext ¶
GetContext reads a single context slot. Returns "" with ErrNotFound when the slot has not been written.
func (*Store) IncrementAccess ¶
IncrementAccess bumps access_count and last_accessed.
func (*Store) List ¶
List returns memories with simple pagination, newest first, including the total count.
func (*Store) ListByScope ¶
ListByScope returns active memories within a scope, newest first.
func (*Store) ListMentalModels ¶
func (s *Store) ListMentalModels(ctx context.Context) ([]MentalModel, error)
ListMentalModels returns all curated rules ordered by most recently updated.
func (*Store) MarkStale ¶
MarkStale marks a memory as superseded by another. It sets ValidTo to now and appends a revision entry recording the supersession.
func (*Store) Parent ¶
Parent returns the underlying cortexdb.DB so callers can compose other CortexDB layers.
func (*Store) Reflect ¶
Reflect collects active facts in scope, asks the Reflector to consolidate them into observations, persists each observation as a new memory, and marks any superseded observations stale.
func (*Store) Save ¶
Save upserts a memory. If m.ID is empty it is generated; CreatedAt / UpdatedAt / ValidFrom are populated when zero.
func (*Store) SearchByScope ¶
func (s *Store) SearchByScope(ctx context.Context, query string, scopes []Scope, opts SearchOptions) ([]ScoredMemory, error)
SearchByScope is SearchByText restricted to a list of scopes.
func (*Store) SearchByText ¶
func (s *Store) SearchByText(ctx context.Context, query string, opts SearchOptions) ([]ScoredMemory, error)
SearchByText runs an FTS5 query, then re-ranks with importance + time decay.
func (*Store) SearchByType ¶
SearchByType returns top-N memories of a given type, ranked by importance + recency (no FTS query). Useful when callers want the latest preferences / observations.
func (*Store) SetContext ¶
func (s *Store) SetContext(ctx context.Context, scope Scope, slot ContextSlot, content string) error
SetContext writes (replaces) the content of a context slot for a given scope.
func (*Store) UsesFallbackTokenizer ¶
UsesFallbackTokenizer reports whether the FTS table fell back from trigram to unicode61. Callers running CJK-heavy workloads on older SQLite builds may want to surface this to users.