Documentation
¶
Overview ¶
Package tier implements the tiered memory subsystem: tier-scoped record stores, a manager that remembers and recalls records across hot/warm/cold levels, and the policies that migrate records between them.
Single durable tier (no composite, no reconcile queue) ¶
A host that only needs durable session memory (e.g. the Postgres tier store) can back the manager with a single-level store directly — no composite and no job queue are required. The store forces its own level on Put and answers List/Count for other levels with empty results, so Remember persists immediately and Recall reads the durable tier:
store, _ := postgres.NewStore(db) // level = warm manager := tier.NewManager(store, tier.SingleLevelPolicy(), nil)
SingleLevelPolicy disables promotion, demotion, TTL, and capacity eviction, so recall-time bookkeeping never migrates records out of the durable tier. Hosts seeding chat history should build records with MessageRecord (optionally WithProvenance), which populates fields exactly like the runtime's own writes.
Approximating a flat "most recent, replayed in order" recall ¶
A flat memory.Repository replays every message in insertion order and consumers typically tail the newest N. RankMemories instead SCORES candidates: score = semantic*lexicalOverlap(query) + recency*exp(-age/168h) + importance*record.Importance, weighted by RecallWeights (defaults {Semantic: 0.5, Recency: 0.3, Importance: 0.2}; zero weights are replaced by those defaults, so use small positive values to de-emphasize a dimension). RecallBudget then caps the selection (default Total 20, split 60%/25%/15% across hot/warm/cold by Normalize). The final output is ALWAYS re-sorted chronologically — ranking only picks what survives, not the replay order. To approximate the flat tail-N behavior:
- recall with an empty query (no semantic signal),
- set weights recency-dominant, e.g. {Semantic: 0.01, Recency: 1.0, Importance: 0.01},
- size RecallBudget.Total at the replay window (e.g. 200) and raise the per-level caps to match.
Index ¶
- func RecordTierDepth(ctx context.Context, store Store, recorder observability.Recorder, ...)
- func WithMigrationRunID(ctx context.Context, runID string) context.Context
- type ChainedMigrationObserver
- func (o ChainedMigrationObserver) Demoted(ctx context.Context, ns memory.Namespace, recordID string, from, to Level)
- func (o ChainedMigrationObserver) Evicted(ctx context.Context, ns memory.Namespace, recordID string, from Level)
- func (o ChainedMigrationObserver) Promoted(ctx context.Context, ns memory.Namespace, recordID string, from, to Level)
- type ChatMessage
- type CognitiveAdapter
- type ColdSummaryBackend
- type ColdSummaryIndexer
- type ColdSummarySettings
- type CompositeStore
- func (c *CompositeStore) Count(ctx context.Context, ns memory.Namespace, level Level) (int, error)
- func (c *CompositeStore) Delete(ctx context.Context, ns memory.Namespace, id string) error
- func (c *CompositeStore) Get(ctx context.Context, ns memory.Namespace, id string) (Record, error)
- func (c *CompositeStore) List(ctx context.Context, ns memory.Namespace, level Level, limit int) ([]Record, error)
- func (c *CompositeStore) Put(ctx context.Context, ns memory.Namespace, record Record) error
- type ContentSummarizer
- type EventSinkMigrationObserver
- func (o EventSinkMigrationObserver) Demoted(ctx context.Context, ns memory.Namespace, recordID string, from, to Level)
- func (o EventSinkMigrationObserver) Evicted(ctx context.Context, ns memory.Namespace, recordID string, from Level)
- func (o EventSinkMigrationObserver) Promoted(ctx context.Context, ns memory.Namespace, recordID string, from, to Level)
- type IndexRebuilder
- type Level
- type Manager
- type MetricsObserver
- func (o MetricsObserver) Demoted(ctx context.Context, ns memory.Namespace, recordID string, from, to Level)
- func (o MetricsObserver) Evicted(ctx context.Context, ns memory.Namespace, recordID string, from Level)
- func (o MetricsObserver) Promoted(ctx context.Context, ns memory.Namespace, recordID string, from, to Level)
- type MigrationObserver
- type MigrationReport
- type NoopColdSummaryBackend
- type NoopMigrationObserver
- type Policy
- type RecallBudget
- type RecallWeights
- type Record
- type RecordEnumerator
- type SeedOption
- type Settings
- type Store
- type TruncateColdSummaryBackend
- func (b TruncateColdSummaryBackend) Archive(ctx context.Context, ns memory.Namespace, record *Record) error
- func (b TruncateColdSummaryBackend) Delete(ctx context.Context, ns memory.Namespace, recordID string) error
- func (b TruncateColdSummaryBackend) SearchRecordIDs(ctx context.Context, ns memory.Namespace, query string, limit int) ([]string, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RecordTierDepth ¶
func RecordTierDepth(ctx context.Context, store Store, recorder observability.Recorder, scenario string, ns memory.Namespace)
RecordTierDepth publishes per-level record counts for a namespace.
Types ¶
type ChainedMigrationObserver ¶ added in v0.2.0
type ChainedMigrationObserver struct {
Observers []MigrationObserver
}
ChainedMigrationObserver fans out migration notifications to multiple observers.
type ChatMessage ¶ added in v0.3.1
type ChatMessage struct {
Role string `json:"role"`
Content string `json:"content,omitempty"`
ToolCalls []llm.ToolCall `json:"tool_calls,omitempty"`
Tool string `json:"tool,omitempty"`
ToolCallID string `json:"tool_call_id,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
Time time.Time `json:"time"`
}
ChatMessage is the wire format the runtime persists for one chat message inside a tier record's Content field. It intentionally mirrors the runtime's internal message schema field-for-field so records seeded by a host (e.g. chat transcript hydration) are indistinguishable from records the framework writes itself on recall.
type CognitiveAdapter ¶
type CognitiveAdapter struct {
Manager Manager
Weights RecallWeights
Budget func(limit int) RecallBudget
}
CognitiveAdapter implements memory.CognitiveMemory using a tier Manager.
func NewCognitiveAdapter ¶
func NewCognitiveAdapter(manager Manager, weights RecallWeights) *CognitiveAdapter
NewCognitiveAdapter wraps a tier Manager as a CognitiveMemory port.
func (*CognitiveAdapter) Recall ¶
func (a *CognitiveAdapter) Recall(ctx context.Context, ns memory.Namespace, query string, limit int) ([]memory.CognitiveRecord, error)
func (*CognitiveAdapter) Remember ¶
func (a *CognitiveAdapter) Remember(ctx context.Context, ns memory.Namespace, record memory.CognitiveRecord) error
type ColdSummaryBackend ¶ added in v0.2.0
type ColdSummaryBackend interface {
Archive(ctx context.Context, ns memory.Namespace, record *Record) error
SearchRecordIDs(ctx context.Context, ns memory.Namespace, query string, limit int) ([]string, error)
Delete(ctx context.Context, ns memory.Namespace, recordID string) error
}
ColdSummaryBackend archives cold records and optionally indexes summaries for semantic recall.
type ColdSummaryIndexer ¶ added in v0.2.0
type ColdSummaryIndexer interface {
UpsertSummary(ctx context.Context, ns memory.Namespace, record Record, summary string) error
SearchSummaries(ctx context.Context, ns memory.Namespace, query string, limit int) ([]string, error)
DeleteSummary(ctx context.Context, ns memory.Namespace, recordID string) error
}
ColdSummaryIndexer stores and searches cold summaries in a vector index.
type ColdSummarySettings ¶ added in v0.2.0
type ColdSummarySettings struct {
Enabled bool `json:"enabled,omitempty" yaml:"enabled"`
MinBytes int64 `json:"min_bytes,omitempty" yaml:"min_bytes"`
MaxSummaryChars int `json:"max_summary_chars,omitempty" yaml:"max_summary_chars"`
SummaryProfile string `json:"summary_profile,omitempty" yaml:"summary_profile"`
}
ColdSummarySettings configures cold-tier summarization before archive.
type CompositeStore ¶
CompositeStore routes tier records across hot, warm, and cold backends.
type ContentSummarizer ¶ added in v0.2.0
type ContentSummarizer interface {
Summarize(ctx context.Context, content string, maxChars int) (string, error)
}
ContentSummarizer compresses large record content before cold archive.
type EventSinkMigrationObserver ¶ added in v0.2.0
EventSinkMigrationObserver emits tier migration events to a core.EventSink.
type IndexRebuilder ¶ added in v0.3.0
type IndexRebuilder interface {
RebuildIndex(ctx context.Context, ns memory.Namespace) (int, error)
}
IndexRebuilder is an optional Manager capability that re-mirrors the durable tier records into a secondary index (e.g. a cognitive search index), used to converge the index after a transient mirror failure. It returns the number of records re-mirrored.
type Manager ¶
type Manager interface {
Remember(ctx context.Context, ns memory.Namespace, record Record) error
Recall(ctx context.Context, ns memory.Namespace, query string, budget RecallBudget) ([]Record, error)
Reconcile(ctx context.Context, ns memory.Namespace, now time.Time) (MigrationReport, error)
}
Manager orchestrates tiered remember, recall, and reconciliation.
func NewDualWriteManager ¶
func NewDualWriteManager(inner Manager, index memory.CognitiveMemory) Manager
NewDualWriteManager remembers tier records and mirrors searchable cognitive entries.
func NewManager ¶
func NewManager(store Store, policy Policy, observer MigrationObserver) Manager
NewManager constructs a tier Manager backed by store and policy.
func NewManagerWithWeights ¶
func NewManagerWithWeights(store Store, policy Policy, observer MigrationObserver, weights memory.RecallWeights, coldSummary ColdSummaryBackend) Manager
NewManagerWithWeights constructs a tier Manager with custom RankMemories weights.
type MetricsObserver ¶
type MetricsObserver struct {
Recorder observability.Recorder
Scenario string
}
MetricsObserver records tier migration and depth metrics.
type MigrationObserver ¶
type MigrationObserver interface {
Promoted(ctx context.Context, ns memory.Namespace, recordID string, from, to Level)
Demoted(ctx context.Context, ns memory.Namespace, recordID string, from, to Level)
Evicted(ctx context.Context, ns memory.Namespace, recordID string, from Level)
}
MigrationObserver receives tier migration notifications from a Manager.
func ChainMigrationObservers ¶ added in v0.2.0
func ChainMigrationObservers(observers ...MigrationObserver) MigrationObserver
type MigrationReport ¶
type MigrationReport struct {
Promoted int `json:"promoted"`
Demoted int `json:"demoted"`
Evicted int `json:"evicted"`
}
MigrationReport summarizes tier migrations from a reconcile pass.
type NoopColdSummaryBackend ¶ added in v0.2.0
type NoopColdSummaryBackend struct{}
NoopColdSummaryBackend disables cold summary behavior.
type NoopMigrationObserver ¶
type NoopMigrationObserver struct{}
NoopMigrationObserver discards migration notifications.
type Policy ¶
type Policy struct {
HotCapacity int
WarmCapacity int
ColdCapacity int
HotTTL time.Duration
WarmTTL time.Duration
PromoteAccess int
DemoteIdle time.Duration
}
Policy configures automatic promotion, demotion, and eviction between tiers.
func DefaultPolicy ¶
func DefaultPolicy() Policy
DefaultPolicy returns baseline hot/warm/cold promotion and demotion rules.
func SingleLevelPolicy ¶ added in v0.3.1
func SingleLevelPolicy() Policy
SingleLevelPolicy returns a Policy with no promotion, demotion, TTL expiry, or capacity eviction: every record stays in the tier its store assigns. Use it when one durable store (e.g. the Postgres tier store) backs the whole manager without a composite or a reconcile queue, so recall-time bookkeeping never migrates records out of the durable tier and the store's level is the single source of truth.
func (Policy) NextTierOnDemote ¶
NextTierOnDemote returns the colder tier, or empty if eviction is required.
func (Policy) ShouldDemote ¶
ShouldDemote reports whether a record should move to a colder tier.
func (Policy) ShouldPromote ¶
ShouldPromote reports whether a record should move to a hotter tier after access.
type RecallBudget ¶
type RecallBudget struct {
Total int `json:"total"`
Hot int `json:"hot"`
Warm int `json:"warm"`
Cold int `json:"cold"`
}
RecallBudget limits how many records to pull from each tier during recall.
func (RecallBudget) Normalize ¶
func (b RecallBudget) Normalize() RecallBudget
Normalize fills zero values with sensible defaults and caps per-tier limits by Total.
type RecallWeights ¶
type RecallWeights struct {
Semantic float64 `json:"semantic,omitempty" yaml:"semantic"`
Recency float64 `json:"recency,omitempty" yaml:"recency"`
Importance float64 `json:"importance,omitempty" yaml:"importance"`
}
RecallWeights configures RankMemories weighting during tier recall.
type Record ¶
type Record struct {
memory.CognitiveRecord
Tier Level `json:"tier"`
AccessCount int `json:"access_count"`
LastAccessAt time.Time `json:"last_access_at"`
PromotedAt time.Time `json:"promoted_at"`
SizeBytes int64 `json:"size_bytes,omitempty"`
Pinned bool `json:"pinned,omitempty"`
}
Record extends a cognitive memory entry with tier lifecycle metadata.
func MessageRecord ¶ added in v0.3.1
func MessageRecord(ns memory.Namespace, msg ChatMessage, opts ...SeedOption) (Record, error)
MessageRecord builds a tier.Record for one chat message using the same field-population rules the runtime applies to its own memory writes: Content carries the marshaled message, Categories/Importance derive from the role, and the record metadata marks role/kind/searchable. Hosts hydrating chat history into a tier store should seed through this helper (with WithProvenance(memory.ProvenanceIntegrator)) instead of re-implementing the mapping, so framework-side recall treats seeded and runtime-written records identically.
type RecordEnumerator ¶ added in v0.3.0
type RecordEnumerator interface {
ListAll(ctx context.Context, ns memory.Namespace) ([]Record, error)
}
RecordEnumerator is an optional Manager capability that lists every stored record in a namespace across all tiers. It backs index rebuild/reconciliation.
type SeedOption ¶ added in v0.3.1
type SeedOption func(*seedConfig)
SeedOption customizes MessageRecord.
func WithProvenance ¶ added in v0.3.1
func WithProvenance(provenance string) SeedOption
WithProvenance tags the seeded message with a provenance marker (see memory.ProvenanceRunTurn, memory.ProvenanceIntegrator) recorded inside the message metadata, exactly how the runtime tags its own writes. It does not affect recall scoring.
type Settings ¶
type Settings struct {
Enabled bool `json:"enabled,omitempty" yaml:"enabled"`
HotCapacity int `json:"hot_capacity,omitempty" yaml:"hot_capacity"`
WarmCapacity int `json:"warm_capacity,omitempty" yaml:"warm_capacity"`
ColdCapacity int `json:"cold_capacity,omitempty" yaml:"cold_capacity"`
HotTTL time.Duration `json:"hot_ttl,omitempty" yaml:"hot_ttl"`
WarmTTL time.Duration `json:"warm_ttl,omitempty" yaml:"warm_ttl"`
PromoteAccess int `json:"promote_access,omitempty" yaml:"promote_access"`
DemoteIdle time.Duration `json:"demote_idle,omitempty" yaml:"demote_idle"`
RecallBudget RecallBudget `json:"recall_budget,omitempty" yaml:"recall_budget"`
RecallWeights RecallWeights `json:"recall_weights,omitempty" yaml:"recall_weights"`
ColdSummary ColdSummarySettings `json:"cold_summary,omitempty" yaml:"cold_summary"`
}
Settings configures tiered memory for a scenario memory reference.
func SettingsFromCore ¶
func SettingsFromCore(ref *core.MemoryTierSettings) (Settings, bool)
SettingsFromCore converts a scenario memory tier reference into tier settings.
func (Settings) Budget ¶
func (s Settings) Budget() RecallBudget
Budget returns the normalized recall budget for tier recall.
func (Settings) Policy ¶
Policy returns the effective tier policy from settings, overlaying defaults.
func (Settings) Weights ¶
func (s Settings) Weights() memory.RecallWeights
Weights returns normalized RankMemories weights.
type Store ¶
type Store interface {
Put(ctx context.Context, ns memory.Namespace, record Record) error
Get(ctx context.Context, ns memory.Namespace, id string) (Record, error)
List(ctx context.Context, ns memory.Namespace, level Level, limit int) ([]Record, error)
Delete(ctx context.Context, ns memory.Namespace, id string) error
Count(ctx context.Context, ns memory.Namespace, level Level) (int, error)
}
Store persists tier-scoped memory records.
type TruncateColdSummaryBackend ¶ added in v0.2.0
type TruncateColdSummaryBackend struct {
Settings ColdSummarySettings
Vector ColdSummaryIndexer
Summarizer ContentSummarizer
}
TruncateColdSummaryBackend summarizes large records with a deterministic truncate fallback.