memory

package
v0.77.0 Latest Latest
Warning

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

Go to latest
Published: Sep 11, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

capture_rate.go — process-scoped memory capture-rate tracker.

Design: a single global CaptureRateTracker holds a ring buffer of timestamps for the last N successful chunk writes (up to 120 slots, well beyond any 60-second window) so ChunksPerMinute can be computed exactly without a background goroutine.

Thread-safety: all mutations go through a sync.Mutex. The ring buffer is small enough that the lock is never contended for more than a few microseconds.

Embedder health is tracked via two atomic values:

  • lastEmbedLatencyNs: the nanosecond duration of the most recent embedder call (set by RecordEmbedCall).
  • a small ring buffer of recent error timestamps (last 5 min window).

No migrations: all state is in-process memory; it resets on restart.

Long-term memory types. Chunk is the unit the user pins via the chat surface's "remember this" button; the embedding stays out of the JSON wire shape because the frontend never reads it (it is consumed only by the local k-NN search inside core/memory.Store).

Package memory — embedder eligibility check.

EmbedderEligibility walks a slice of ProviderProfile records (same logic as newEmbedderFromProfiles in core/rpc/api.go) but READ-ONLY: it collects metadata about which profiles are eligible and which kinds are present but skipped, without constructing an Embedder.

Eligible kinds (OpenAI-compatible /v1/embeddings shape):

openai, openrouter, custom_openai_compatible, azure

Skipped kinds (no embeddings endpoint or different wire shape):

anthropic — no /v1/embeddings endpoint
bedrock   — AWS Titan uses a different wire shape; deferred

OpenAI-compatible embedder. We mirror core/llm/anthropic's net/http shape (no SDK dependency) so dependency surface stays unchanged.

Package memory — health snapshot computation for the inspector surface.

HealthSnapshot is populated by indexed COUNT passes over the in-RAM chunk slice held by the store; there is no SQL or full-table scan. The Store is gob-backed, so "indexed" means a single slice walk with O(n) complexity — still well within the 200 ms p95 budget for a 100 k-chunk store on modern hardware.

Package memory — retrieval history ring buffer (§2.1 active-session retrieval inspector, memory-inspection-ui-01KX5R8E WP02).

The retriever pushes a RetrievalRecord after every successful call; the RPC surface reads the most recent record for a session to power the "Last turn retrieval" inspector panel.

Design constraints:

  • Bounded: per-session cap 200, global cap 10k (oldest entry pruned first).
  • Process-scoped singleton via GlobalRetrievalHistory(); never persisted.
  • Concurrency-safe: single RWMutex guards all state.

Cross-session retrieval glue. The Retriever wraps Store + Embedder behind a single small surface the LLM impl can call without taking a hard dependency on either concrete type. The opt-in gate is read per-call via the EnabledFn so toggling memory in settings takes effect on the next send without restarting the harness.

Long-term memory vector store. The Store interface lets the rpc layer treat the persistence and the in-RAM index as a single seam; the default implementation is a gob-encoded snapshot with a flat cosine-similarity scan.

Why a flat scan instead of an external vector DB: the design notes called for chromem-go (pure-Go, file-backed). The harness build environment cannot fetch new module proxies, so we ship an in-house equivalent with the same on-disk + interface contract. Swapping in a chromem-go-backed implementation later is a one-file change because every caller goes through Store.

Privacy posture: the file is created mode 0600. The embedding column is JSON-omitted (`json:"-"`) so when a future export path round-trips chunks through JSON, the user's vector representations stay local.

Index

Constants

View Source
const (
	ScopeKindGlobal  = "global"
	ScopeKindProject = "project"
	ScopeKindSession = "session"
	// ScopeKindLongTerm is the long-term scope tier added by the narrative
	// layer (memory-narrative-layer-01KQ8TD1 WP09). Chunks promoted to
	// long_term resist the prune sweep and are loaded into the system-prompt
	// prelude at session start. One-way promotion: demotion requires an
	// explicit pruner verdict, not a score drop.
	ScopeKindLongTerm = "long_term"
)

Scope kinds. Mirrors claude-mem's scope dimension: a chunk is either global (visible across every session), project-scoped (visible to every session inside a Project), or session-scoped (the default — visible only to the originating session).

View Source
const (
	// HistoryPerSessionCap is the maximum number of RetrievalRecord entries
	// kept per session-ID key in the ring buffer.
	HistoryPerSessionCap = 200
	// HistoryGlobalCap is the hard upper bound on total RetrievalRecord rows
	// across all sessions. When reached, the oldest entry (by any session) is
	// evicted before the new one is inserted.
	HistoryGlobalCap = 10_000
)
View Source
const DedupWindow = 30 * time.Second

DedupWindow is the look-back window inside which an Add with a matching ContentHash + scope is rejected as a duplicate. Mirrors claude-mem's behaviour: the same content can be re-pinned later.

Variables

View Source
var ErrDuplicate = errors.New("memory: duplicate chunk within dedup window")

ErrDuplicate is returned by Add when a chunk with the same scope + content hash was added inside DedupWindow.

View Source
var ErrEmbedderUnavailable = errors.New("memory: embedder unavailable")

ErrEmbedderUnavailable is returned when the harness has no working embedder configured. Surfaces in the rpc layer as a typed error so the UI can render "configure an OpenAI provider to enable memory".

Functions

func HashContent

func HashContent(content string) string

HashContent returns the hex-encoded sha256 of content. Used by the store to compute ContentHash on Add when the caller leaves it empty and to backfill old gobs that predate the column.

Types

type ActivityWindow

type ActivityWindow struct {
	// Captured is the number of chunks created in the last 7 days.
	Captured int
	// Pruned is always 0 at snapshot time — the prune sweep removes rows;
	// we cannot reconstruct the pre-prune count without a journal.
	// Reserved for a future audit-journal integration.
	Pruned int
	// Promoted is the number of chunks promoted to "global" scope in the
	// last 7 days (CreatedAt used as a proxy because promotion uses
	// move semantics — it deletes + re-inserts with a fresh CreatedAt).
	Promoted int
}

ActivityWindow summarises chunk activity over the last 7 days.

type CaptureRateSnapshot

type CaptureRateSnapshot struct {
	ChunksPerMinute  float64    // writes in the last 60s
	EmbedderHealth   string     // "ok" | "slow" | "error"
	LastErrorAt      *time.Time // nil when no recent error
	RecentErrorCount int        // errors in the last embedErrorWindow
}

CaptureRateSnapshot is the computed snapshot returned to the RPC surface.

type CaptureRateTracker

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

CaptureRateTracker tracks memory capture velocity and embedder health. The zero value is ready to use.

func GlobalCaptureTracker

func GlobalCaptureTracker() *CaptureRateTracker

GlobalCaptureTracker returns the process-scoped capture rate tracker. The pointer is stable for the process lifetime.

func (*CaptureRateTracker) RecordEmbedCall

func (t *CaptureRateTracker) RecordEmbedCall(d time.Duration)

RecordEmbedCall records the latency of one embedder call. Call this after every Embed() invocation regardless of success.

func (*CaptureRateTracker) RecordEmbedError

func (t *CaptureRateTracker) RecordEmbedError(at time.Time)

RecordEmbedError records one embedder error at the given time.

func (*CaptureRateTracker) RecordWrite

func (t *CaptureRateTracker) RecordWrite(at time.Time)

RecordWrite records one successful chunk write at the given time. Call this immediately after Store.Add returns nil.

func (*CaptureRateTracker) Snapshot

Snapshot computes the current capture-rate snapshot. now is injected so callers can pass time.Now().UTC() in production and a fixed time in tests.

type Chunk

type Chunk struct {
	ID            string    `json:"id"`
	SessionID     string    `json:"session_id,omitempty"`
	ProjectID     string    `json:"project_id,omitempty"`
	ScopeKind     string    `json:"scope_kind"`
	ScopeID       string    `json:"scope_id"`
	SourceTurn    string    `json:"source_turn,omitempty"`
	Content       string    `json:"content"`
	ContentHash   string    `json:"content_hash"`
	ToolName      string    `json:"tool_name,omitempty"`
	FilesRead     []string  `json:"files_read,omitempty"`
	FilesModified []string  `json:"files_modified,omitempty"`
	Title         string    `json:"title,omitempty"`
	Embedding     []float32 `json:"-"`
	CreatedAt     time.Time `json:"created_at"`
	// Pinned chunks are immune to the prune sweep (FR-028).
	Pinned bool `json:"pinned,omitempty"`
	// RecallCount is the number of times this chunk has been retrieved
	// by the kernel's MemoryNode / retriever. Updated lazily — the
	// production store is the canonical recorder. Used by the
	// recall-frequency prune signal.
	RecallCount int `json:"recall_count,omitempty"`
	// LastAccessed is the last time this chunk was read out of the
	// store. Defaults to CreatedAt when zero. Used by the staleness
	// prune signal.
	LastAccessed time.Time `json:"last_accessed,omitempty"`
	// Source records the originating hook boundary ("post-llm" etc.)
	// so the inspector can show users why a chunk was captured.
	Source string `json:"source,omitempty"`
	// Kind classifies the chunk in the narrative layer
	// (memory-narrative-layer-01KQ8TD1 WP01). One of: "raw",
	// "narrative_extractive", "narrative_synthesised",
	// "narrative_extractive_fallback". Empty values are backfilled to
	// "raw" on load so legacy gobs are transparent.
	Kind string `json:"kind,omitempty"`
	// RetrievalWeight is the score multiplier applied during similarity
	// search (WP01). Default 1.0 (no boost). Narrative chunks default
	// to 1.5 (set by the narrative layer at write time). Zero values
	// are backfilled to 1.0 on load.
	RetrievalWeight float32 `json:"retrieval_weight,omitempty"`
	// TurnID links this chunk to a specific agent turn for narrative
	// keying. Used by the Promoter to correlate synthesised narratives
	// with their extractive fallbacks. Empty for raw chunks.
	TurnID string `json:"turn_id,omitempty"`
}

Chunk is one stored memory: an opt-in snippet the user explicitly asked the harness to keep across sessions.

Greedy-memory addendum (Bundle E WP15): the Pinned, RecallCount, and LastAccessed fields drive the background prune sweep. They default to the "fresh chunk" values when an old gob is read back (Pinned=false, RecallCount=0, LastAccessed=CreatedAt) so existing on-disk stores keep working without a migration.

Narrative-layer addendum (memory-narrative-layer-01KQ8TD1 WP01): Kind and RetrievalWeight were added without a gob schema migration. Existing on-disk stores read back with empty Kind and zero RetrievalWeight; backfillChunkDefaults in store.go sets them to "raw" and 1.0 so the retriever's score multiplier is transparent for legacy chunks.

type ChunkCounts

type ChunkCounts struct {
	// Total is the grand total number of chunks in the store.
	Total int
	// Raw is the count of chunks with ScopeKind "session".
	// Named "raw" in the UI to match the spec's §2.4 display.
	Raw int
	// Narrative is the count of chunks with ScopeKind "narrative"
	// (reserved for the future memory-narrative-layer; always 0 until
	// that ship).
	Narrative int
	// LongTermPromoted is the count of chunks with ScopeKind "long_term"
	// or "global". "global" is the current promotion target; long_term
	// is reserved for a future scope tier.
	LongTermPromoted int
	// Embedded is the count of chunks that have a non-empty embedding
	// vector (i.e. they can be retrieved by the k-NN search path).
	Embedded int
	// Unembedded is the count of chunks with an empty embedding vector.
	// These are unretrievable until the user triggers re-embedding.
	Unembedded int
}

ChunkCounts holds the per-kind breakdown of the total chunk count.

type Embedder

type Embedder interface {
	Kind() string
	Dimensions() int
	Embed(ctx context.Context, texts []string) ([][]float32, error)
}

Embedder turns text into vectors the Store can index. The interface is small on purpose — swapping providers (OpenAI, a local model, a mock for tests) is a one-implementation change.

type EmbedderEligibility

type EmbedderEligibility struct {
	// HasEligible is true when at least one profile in AllProfiles is
	// eligible for use as an embedder.
	HasEligible bool `json:"hasEligible"`
	// AllProfiles is the total count of profiles that were examined.
	AllProfiles int `json:"allProfiles"`
	// EligibleProfiles is the count of profiles that are eligible.
	EligibleProfiles int `json:"eligibleProfiles"`
	// SkippedKinds holds the unique provider kinds that were present in
	// the profile list but are not eligible (e.g. "anthropic", "bedrock").
	// The frontend uses this list to render per-provider explanations in
	// the "no memory provider" banner.
	SkippedKinds []string `json:"skippedKinds"`
}

EmbedderEligibility reports which provider profiles are capable of supplying embeddings. It is designed to be called cheaply at settings load time so the frontend can surface a contextual banner when the user has only Anthropic-direct or Bedrock profiles.

func CheckEligibility

func CheckEligibility(profiles []ProfileEligibilityInput) EmbedderEligibility

CheckEligibility walks profiles and returns an EmbedderEligibility summary. The logic mirrors newEmbedderFromProfiles's eligibleEmbedder inner function — but without constructing any network objects.

type EmbedderInfo

type EmbedderInfo struct {
	// Kind is the short provider tag ("openai", "noop", "fake", …).
	Kind string
	// Model is the embedding model identifier (e.g. "text-embedding-3-small").
	// Empty for the noop embedder.
	Model string
	// Dimensions is the expected vector width. Zero for the noop embedder.
	Dimensions int
}

EmbedderInfo surfaces the static properties of the currently-wired Embedder so the health panel can render "Provider / Model / Dimensions" without a network call.

type Extractor

type Extractor interface {
	Apply(prev Snapshot, e event.Event) (Snapshot, bool)
}

type GateSetter

type GateSetter interface {
	SetGate(g MemoryWriteGate)
}

GateSetter is the optional capability tests + the rpc layer use to install a policy gate without re-opening the store. The chromem store implements it.

type HealthSnapshot

type HealthSnapshot struct {
	Counts   ChunkCounts    `json:"counts"`
	Activity ActivityWindow `json:"activity"`
	Embedder EmbedderInfo   `json:"embedder"`
	// CapturedAt is when the snapshot was taken (UTC).
	CapturedAt time.Time `json:"capturedAt"`
}

HealthSnapshot is the wire-shape returned by HealthSnapshot(). All counts come from a single O(n) pass over the in-RAM store; there are no full-table scans or additional network calls.

func SnapshotHealth

func SnapshotHealth(chunks []Chunk, embedder Embedder, now time.Time) HealthSnapshot

SnapshotHealth builds a HealthSnapshot over the given chunk slice. Called by chromemStore.SnapshotHealth after it acquires a read lock. Pure function — no I/O, safe for benchmarking.

type HealthSnapshotter

type HealthSnapshotter interface {
	SnapshotHealth(ctx context.Context) (HealthSnapshot, error)
}

HealthSnapshotter is the optional capability the Store must expose for the health-snapshot path. The chromemStore satisfies it via the SnapshotHealth helper below; test stubs and future backends can implement it directly.

The interface lives in core/memory (not core/rpc/views/memory) so the view layer never has to import core/memory internals beyond value types (DIRECTIVE_001 compliance).

type KeyResolver

type KeyResolver func(ctx context.Context) ([]byte, error)

KeyResolver fetches the plaintext API key for a given OpenAI-kind provider. The rpc layer wires this against the credref resolver + secrets backend; tests pass a fake.

type MemoryWriteGate

type MemoryWriteGate interface {
	CheckWrite(ctx context.Context, scope string) error
}

MemoryWriteGate is the narrow interface chromemStore consults on every Add. core/policy/cedar.Gate satisfies it via CheckMemoryWrite adapter; tests can pass a stub. The interface lives here to avoid pulling cedar into core/memory's import graph (DIRECTIVE_001).

type NoopEmbedder

type NoopEmbedder struct{}

NoopEmbedder is the safe-by-default embedder used when no real one is wired. Embed always errors with ErrEmbedderUnavailable so the rpc layer can short-circuit "remember this" without persisting an unembedded chunk.

func (NoopEmbedder) Dimensions

func (NoopEmbedder) Dimensions() int

func (NoopEmbedder) Embed

func (NoopEmbedder) Embed(_ context.Context, _ []string) ([][]float32, error)

func (NoopEmbedder) Kind

func (NoopEmbedder) Kind() string

type OpenAIEmbedder

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

OpenAIEmbedder is an Embedder backed by an OpenAI-compatible /v1/embeddings endpoint. Several provider Kinds reuse this type (openai, openrouter, custom_openai_compatible, azure) by overriding the endpoint via WithOpenAIEndpoint. Kind() reports the SOURCE provider Kind set via WithOpenAISourceKind so the health UI shows the actual upstream the user configured rather than the literal implementation type.

func NewOpenAIEmbedder

func NewOpenAIEmbedder(resolveKey KeyResolver, opts ...OpenAIOption) *OpenAIEmbedder

NewOpenAIEmbedder constructs an OpenAI embedder. resolveKey is required; pass NoopEmbedder when no provider is configured.

func (*OpenAIEmbedder) Dimensions

func (e *OpenAIEmbedder) Dimensions() int

func (*OpenAIEmbedder) Embed

func (e *OpenAIEmbedder) Embed(ctx context.Context, texts []string) ([][]float32, error)

Embed posts texts to /v1/embeddings and returns one vector per input in the same order. Errors mirror the anthropic adapter's classify pattern: HTTP non-2xx becomes a wrapped error including the upstream body for support visibility.

func (*OpenAIEmbedder) Kind

func (e *OpenAIEmbedder) Kind() string

Kind returns the SOURCE provider Kind (the upstream the user configured: "openai", "openrouter", "azure", "custom_openai_compatible"). Falls back to "openai" when no source was set, matching pre-v0.5.5 behaviour for callers that build embedders directly without going through newEmbedderFromProfiles.

type OpenAIOption

type OpenAIOption func(*OpenAIEmbedder)

OpenAIOption configures an OpenAIEmbedder.

func WithOpenAIEndpoint

func WithOpenAIEndpoint(u string) OpenAIOption

WithOpenAIEndpoint overrides the embeddings URL.

func WithOpenAIHTTPClient

func WithOpenAIHTTPClient(c *http.Client) OpenAIOption

WithOpenAIHTTPClient overrides the http client (tests use httptest).

func WithOpenAIModel

func WithOpenAIModel(m string) OpenAIOption

WithOpenAIModel overrides the embedding model id.

func WithOpenAISourceKind

func WithOpenAISourceKind(k string) OpenAIOption

WithOpenAISourceKind sets the provider Kind that originated this embedder (e.g. "openrouter", "azure", "custom_openai_compatible"). Reported via Kind() so the health dashboard surfaces the actual upstream the user picked, not the literal "openai" implementation. Empty string falls back to "openai" for backwards compatibility with callers that don't set it.

type ProfileEligibilityInput

type ProfileEligibilityInput struct {
	Kind     string
	Endpoint string // only relevant for custom_openai_compatible and azure
	// AzureComplete mirrors the Defaults map check in newEmbedderFromProfiles:
	// true when deployment_id, api_version, and resource_name are all non-empty.
	AzureComplete bool
}

ProfileEligibilityInput is the minimal profile fields CheckEligibility needs. Keeping this separate from core/llm.ProviderProfile avoids a circular import; the rpc layer maps ProviderProfile → ProfileEligibilityInput before calling CheckEligibility (see core/rpc/views/memory/impl.go).

type PruneCapable

type PruneCapable interface {
	SetPinned(ctx context.Context, id string, pinned bool) error
	MarkAccessed(ctx context.Context, ids []string, at time.Time) error
}

PruneCapable is the optional capability the prune sweep uses to mark recall hits, pin/unpin chunks, and bulk-delete based on the pruner's verdict. Stores that don't implement it fall through to per-id Delete and the slower path the inspector RPC uses today.

SetPinned with pinned=true makes the chunk immune to the prune sweep (FR-028). MarkAccessed bumps RecallCount and updates LastAccessed atomically — the retriever should call it after every successful read so the prune sweep's recall-frequency signal reflects real usage.

type Result

type Result struct {
	Chunk      Chunk
	Similarity float32
}

Result pairs a Chunk with its similarity score against a query embedding. Similarity is cosine; values close to 1 mean "highly related", values near 0 mean "unrelated".

type RetrievalHistory

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

RetrievalHistory is the process-scoped ring buffer.

func GlobalRetrievalHistory

func GlobalRetrievalHistory() *RetrievalHistory

GlobalRetrievalHistory returns the process-scoped singleton.

func (*RetrievalHistory) Last

func (h *RetrievalHistory) Last(sessionID string) (RetrievalRecord, bool)

Last returns the most recent RetrievalRecord for the given session, and true when found. Returns zero-value, false when the session has no history.

func (*RetrievalHistory) Push

func (h *RetrievalHistory) Push(rec RetrievalRecord)

Push records a retrieval call into the ring buffer. Enforces per-session and global caps, evicting oldest entries as needed.

func (*RetrievalHistory) Total

func (h *RetrievalHistory) Total() int

Total returns the current total number of records across all sessions. Used in tests.

type RetrievalRecord

type RetrievalRecord struct {
	SessionID string
	Query     string
	// Results holds ALL k-NN hits, sorted by similarity descending.
	// The rpc layer partitions them into "injected" vs "below threshold"
	// based on the retriever's configured threshold.
	Results   []RetrievalResult
	Threshold float32
	At        time.Time
}

RetrievalRecord captures the outcome of one Retriever.retrieve call. It is the wire-agnostic internal shape; the rpc layer projects it into the frontend-visible RetrievalReport.

type RetrievalResult

type RetrievalResult struct {
	ChunkID    string
	Content    string
	Kind       string
	Pinned     bool
	Similarity float32
	Injected   bool // true when similarity >= threshold
}

RetrievalResult is one ranked chunk from a retrieval call.

type Retriever

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

Retriever is the surface buildMessages calls to inject relevant snippets into the prompt. The concrete implementation lives here; callers use the Retrieve method only.

func NewRetriever

func NewRetriever(store Store, embedder Embedder, enabledFn func() bool, threshold float32) *Retriever

NewRetriever constructs a Retriever. enabledFn is the settings-backed opt-in gate; nil means always disabled (safe default). threshold is the minimum cosine similarity a snippet must clear to be injected.

func (*Retriever) Retrieve

func (r *Retriever) Retrieve(ctx context.Context, query string, k int) ([]Snippet, error)

Retrieve embeds query and returns up to k snippets above the configured similarity threshold. No scope filter is applied — every chunk is a candidate. The scoped variant (RetrieveScoped) is the WP06 contract; this thin wrapper is what older callers (and the rpc adapter that has not yet been updated to thread project id) hit.

func (*Retriever) RetrieveScoped

func (r *Retriever) RetrieveScoped(ctx context.Context, query, sessionID, projectID string, k int) ([]Snippet, error)

RetrieveScoped runs a scope-union k-NN: global ∪ project:projectID ∪ session:sessionID. Empty sessionID or projectID drops the matching filter so callers can opt into whichever scopes apply (the persist path before WP02 lands has no project yet, for example).

func (*Retriever) WithSessionID

func (r *Retriever) WithSessionID(sessionID string) *Retriever

WithSessionID returns a copy of the Retriever that records retrieval decisions into GlobalRetrievalHistory under the given session ID.

NARROWED 2026-08-20 (controls-and-readouts-that-tell-the-truth- 01PMZ808 WP11, FR-015): only the RetrieveScoped hook path calls this (core/rpc/api.go's retrieverAdapter.RetrieveScoped) — the sibling Retrieve path (retrieverAdapter.Retrieve) has no sessionID parameter to thread and does not call WithSessionID, so a retrieval driven through that path is not recorded into GlobalRetrievalHistory. The bare constructor still omits it for backwards compatibility / standalone (non-hooks) callers.

type ScopeFilter

type ScopeFilter struct {
	Kind string
	ID   string
}

ScopeFilter targets chunks by (kind, id) for List / Query / Delete. An empty ID matches every chunk of the given kind (used for global, where ScopeID is always empty).

type ScopePromoter

type ScopePromoter interface {
	PromoteScope(ctx context.Context, oldID, newID, newScopeKind, newScopeID string) error
}

ScopePromoter is the optional capability the rpc/memory view uses to implement move semantics for "promote to project/global". The chromem-go-replacement store implements it; future backends should satisfy this interface so the view layer keeps the same contract.

type Snapshot

type Snapshot struct {
	SessionID string            `json:"session_id"`
	Watermark int64             `json:"watermark"`
	Entries   map[string]string `json:"entries"`
}

type Snippet

type Snippet struct {
	Content    string
	Similarity float32
}

Snippet is the shape returned to callers — a content string + score. Mirrors llm.MemorySnippet so the rpc/views/llm package can consume it without importing core/memory directly.

type Store

type Store interface {
	Add(ctx context.Context, chunk Chunk) error
	Delete(ctx context.Context, id string) error
	List(ctx context.Context, scopes ...ScopeFilter) ([]Chunk, error)
	Query(ctx context.Context, embedding []float32, k int, scopes ...ScopeFilter) ([]Result, error)
	Close() error
}

Store is the long-term-memory persistence + retrieval contract.

func NewChromemStore

func NewChromemStore(path string) (Store, error)

NewChromemStore opens (or creates) the on-disk vector DB at path. A missing file is treated as an empty store; a corrupt file surfaces as an error so the user sees the problem instead of silently losing every memory.

type View

type View interface {
	At(ctx context.Context, sessionID string, watermark int64) (*Snapshot, error)
	Latest(ctx context.Context, sessionID string) (*Snapshot, error)
}

Directories

Path Synopsis
Package narrative implements the memory narrative layer (mission memory-narrative-layer-01KQ8TD1).
Package narrative implements the memory narrative layer (mission memory-narrative-layer-01KQ8TD1).
Package prune is the background memory-prune subsystem (Bundle E WP15 of the agent-kernel-graph mission).
Package prune is the background memory-prune subsystem (Bundle E WP15 of the agent-kernel-graph mission).

Jump to

Keyboard shortcuts

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