memory

package
v0.9.1 Latest Latest
Warning

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

Go to latest
Published: Jun 21, 2026 License: MIT Imports: 33 Imported by: 0

Documentation

Index

Constants

View Source
const (
	PreferenceScopeUser    = "user"
	PreferenceScopeProject = "project"
	PreferenceScopeTeam    = "team"
)

v1 scope constants (existing)

View Source
const (
	MemoryTypeSemantic    = "semantic"
	MemoryTypeEpisodic    = "episodic"
	MemoryTypeOperational = "operational"

	ScopeUser    = "user"
	ScopeProject = "project"
	ScopeTeam    = "team"

	OriginManual     = "manual"
	OriginHook       = "hook"
	OriginBootstrap  = "bootstrap"
	OriginDream      = "dream"
	OriginRemote     = "remote"
	OriginHandoff    = "handoff"
	OriginPrecompact = "precompact"
	OriginImport     = "import"

	ContextTierL0 = "L0"
	ContextTierL1 = "L1"
	ContextTierL2 = "L2"

	CurationStatusLowSignal = "low_signal"

	// CurationRule values explaining a low_signal demotion.
	CurationRuleQuality      = "quality"      // mechanical quality score below threshold
	CurationRuleNeverUsed    = "never_used"   // injected many times, never drawn on
	CurationRuleConsolidated = "consolidated" // raw member of a synthesized cluster

	// NeverUsedInjectionFloor is how many injections a memory gets before a
	// zero used_count demotes it (Feature D). Generous on purpose: ten chances
	// to prove useful before the feedback loop pulls it out of rotation.
	NeverUsedInjectionFloor = 10

	// RemoteQualityThreshold: minimum quality_score for remote sync eligibility.
	// Referenced by preview, IsRemoteSyncCandidate, and hybrid search demotion.
	RemoteQualityThreshold = 0.55

	// QualityScorerVersion identifies the current ScoreQuality formula. It is
	// stamped onto metadata whenever a memory is (re)curated. The serve-time
	// worker and `curation reconcile` treat any memory whose scorer_version is
	// missing or lower than this as a candidate, so formula changes re-flow
	// through the whole corpus instead of only touching brand-new memories.
	// v3: usage-feedback demotion (never_used) joined the recurate pass.
	QualityScorerVersion = 3
)

v2 lifecycle constants

View Source
const LegacyModelName = "all-MiniLM-L6-v2"

Variables

This section is empty.

Functions

func ApplyQualityMetadata added in v0.5.5

func ApplyQualityMetadata(metadata any, content, category string, hasProject bool) any

func Categorize

func Categorize(content string) string

func ExpandQueryAdvanced added in v0.2.0

func ExpandQueryAdvanced(query string) string

ExpandQueryAdvanced takes a raw user query and produces an FTS5-compatible query string. It handles:

  • Quoted phrases: "exact phrase" → preserved as FTS5 phrase
  • NEAR operator: word1 NEAR/5 word2 → preserved
  • Standalone words: prefix expansion (word*) + synonym expansion
  • Accent normalization before FTS5 generation

func ExpandQueryForFTS

func ExpandQueryForFTS(keywords []string) string

func ExtractKeywords

func ExtractKeywords(query string) []string

func Migrate

func Migrate(db *sql.DB) error

func NormalizeAccents added in v0.2.0

func NormalizeAccents(s string) string

func NormalizeContextTier added in v0.5.0

func NormalizeContextTier(tier string) string

func NormalizeMemoryType added in v0.5.0

func NormalizeMemoryType(t string) string

func NormalizeOrigin added in v0.5.0

func NormalizeOrigin(o string) string

func NormalizePreferenceScope added in v0.5.0

func NormalizePreferenceScope(scope string) string

func NormalizeScope added in v0.5.0

func NormalizeScope(s string) string

func ScoreQuality added in v0.5.5

func ScoreQuality(content, category string, hasProject bool) float64

func SplitOnPunctuation

func SplitOnPunctuation(text string) []string

func TruncateAtBoundary

func TruncateAtBoundary(s string, maxBytes int) string

func VectorNorm

func VectorNorm(v []float32) float64

func WithPreferenceScope added in v0.5.0

func WithPreferenceScope(metadata any, category, scope string) any

Types

type DeleteScopeOptions added in v0.2.0

type DeleteScopeOptions struct {
	ProjectID string
	Category  string
	Source    string
	Hard      bool
}

type EmbeddingCache

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

func NewEmbeddingCache

func NewEmbeddingCache(db *sql.DB, logger *slog.Logger) *EmbeddingCache

func (*EmbeddingCache) Get

func (c *EmbeddingCache) Get(ctx context.Context, text, model string) ([]float32, bool)

func (*EmbeddingCache) MigrateFromLegacy added in v0.2.0

func (c *EmbeddingCache) MigrateFromLegacy(currentModel string) int64

func (*EmbeddingCache) Put

func (c *EmbeddingCache) Put(ctx context.Context, text, model string, vec []float32, quantize bool) error

type EmbeddingProvider

type EmbeddingProvider interface {
	Embed(ctx context.Context, texts []string) ([][]float32, error)
	Dimensions() int
	Name() string
	Model() string
	Close() error
}

type EntityDetector added in v0.2.0

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

func NewEntityDetector added in v0.2.0

func NewEntityDetector(db *sql.DB, cfg EntityDetectorConfig, logger *slog.Logger) *EntityDetector

func (*EntityDetector) Detect added in v0.2.0

func (d *EntityDetector) Detect(text string) []string

func (*EntityDetector) Refresh added in v0.2.0

func (d *EntityDetector) Refresh(ctx context.Context) error

type EntityDetectorConfig added in v0.2.0

type EntityDetectorConfig struct {
	CacheTTL    time.Duration
	MaxTokens   int
	MinTokenLen int
}

func DefaultEntityDetectorConfig added in v0.2.0

func DefaultEntityDetectorConfig() EntityDetectorConfig

type FastTokenizer added in v0.2.0

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

FastTokenizer parses HuggingFace tokenizer.json and produces ONNX-compatible input_ids matching Python transformers output.

func NewFastTokenizer added in v0.2.0

func NewFastTokenizer(tokenizerPath string, maxLen int) (*FastTokenizer, error)

NewFastTokenizer loads a HuggingFace tokenizer.json and builds a FastTokenizer.

func (*FastTokenizer) Tokenize added in v0.2.0

func (ft *FastTokenizer) Tokenize(text string) (inputIDs, attentionMask, tokenTypeIDs []int64)

type HybridSearchConfig

type HybridSearchConfig struct {
	VectorWeight              float64
	BM25Weight                float64
	MaxResults                int
	MinScore                  float64
	MMREnabled                bool
	MMRLambda                 float64
	TemporalDecayEnabled      bool
	TemporalDecayHalfLifeDays int
}

func DefaultHybridSearchConfig

func DefaultHybridSearchConfig() HybridSearchConfig

type HybridSearcher

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

func NewHybridSearcher

func NewHybridSearcher(store Store, embedder EmbeddingProvider, cache *EmbeddingCache, vectorCache *VectorCache, cfg HybridSearchConfig, entityDetector *EntityDetector, topicChangeDetector *TopicChangeDetector, logger *slog.Logger) *HybridSearcher

func (*HybridSearcher) Search

func (h *HybridSearcher) Search(ctx context.Context, query string, opts ...SearchOptions) ([]SearchResult, error)

type ImportRecord added in v0.2.0

type ImportRecord struct {
	ID               string
	Source           string
	Path             string
	MemoriesImported int
	EntitiesImported int
	Status           string
	StartedAt        *time.Time
	FinishedAt       *time.Time
	Error            string
}

type ListOptions

type ListOptions struct {
	Limit    int
	Offset   int
	Category string
	// Categories lets callers filter on multiple categories with one query.
	// When non-empty, takes precedence over Category. Use it for L0 context
	// builders that want decision/learning/plan/preference/fact in one shot.
	Categories     []string
	ProjectID      string
	Source         string
	IncludeDeleted bool
}

type Memory

type Memory struct {
	ID               string     `json:"id"`
	ProjectID        *string    `json:"project_id,omitempty"`
	Category         string     `json:"category"`
	Content          string     `json:"content"`
	ContentHash      string     `json:"content_hash,omitempty"`
	Keywords         []string   `json:"keywords,omitempty"`
	Embedding        []float32  `json:"embedding,omitempty"`
	Source           string     `json:"source"`
	SourceID         *string    `json:"source_id,omitempty"`
	CreatedAt        time.Time  `json:"created_at"`
	UpdatedAt        time.Time  `json:"updated_at"`
	DeletedAt        *time.Time `json:"deleted_at,omitempty"`
	AccessCount      int        `json:"access_count"`
	LastAccessed     *time.Time `json:"last_accessed,omitempty"`
	Metadata         any        `json:"metadata,omitempty"`
	SyncDirty        bool       `json:"sync_dirty,omitempty"`
	SyncOrigin       string     `json:"sync_origin,omitempty"`
	Author           *string    `json:"author,omitempty"`
	RemoteProjectKey *string    `json:"remote_project_key,omitempty"`
}

type MemoryIndexer added in v0.2.0

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

MemoryIndexer watches directories and incrementally indexes markdown/jsonl files. It uses polling (os.Stat) instead of filesystem events to avoid external dependencies.

func NewMemoryIndexer added in v0.2.0

func NewMemoryIndexer(svc *Service, paths []string, logger *slog.Logger) *MemoryIndexer

func (*MemoryIndexer) IndexNow added in v0.2.0

func (idx *MemoryIndexer) IndexNow(path string) error

IndexNow triggers immediate indexing of a specific file or directory.

func (*MemoryIndexer) SetInterval added in v0.2.0

func (idx *MemoryIndexer) SetInterval(d time.Duration)

SetInterval changes the polling interval. Must be called before Start.

func (*MemoryIndexer) Start added in v0.2.0

func (idx *MemoryIndexer) Start()

Start performs initial indexing of all watched paths, then starts a background goroutine that polls for changes.

func (*MemoryIndexer) Stop added in v0.2.0

func (idx *MemoryIndexer) Stop()

Stop terminates the background polling goroutine.

type MemoryMetadata added in v0.2.0

type MemoryMetadata struct {
	// v1 fields (existing, unchanged)
	Source        string   `json:"source,omitempty"`         // "user", "auto_capture", "dream", "import", "precompact"
	SessionID     string   `json:"session_id,omitempty"`     // Source session that created this memory
	Consolidated  []string `json:"consolidated,omitempty"`   // IDs of memories merged into this one
	DreamVersion  string   `json:"dream_version,omitempty"`  // Dream run ID that processed this
	CaptureReason string   `json:"capture_reason,omitempty"` // Why this was captured
	QualityScore  float64  `json:"quality_score,omitempty"`  // Auto-capture quality score
	// PreferenceScope distinguishes personal preferences from project/team conventions.
	// Valid values: "user", "project", "team". Empty means unknown/non-preference.
	PreferenceScope string `json:"preference_scope,omitempty"`

	// v2 lifecycle fields (all optional, zero-value means unset)
	MemoryType     string   `json:"memory_type,omitempty"`  // "semantic", "episodic", "operational"
	Kind           string   `json:"kind,omitempty"`         // "fact", "decision", "learning", "summary", "rule", "handoff", "precompact"
	Scope          string   `json:"scope,omitempty"`        // "user", "project", "team"
	Origin         string   `json:"origin,omitempty"`       // "manual", "hook", "bootstrap", "dream", "remote", "handoff", "precompact", "import"
	Importance     float64  `json:"importance,omitempty"`   // 0.0..1.0 ranking and retention hint
	Pinned         bool     `json:"pinned,omitempty"`       // exempt from retention and demotion
	ExpiresAt      string   `json:"expires_at,omitempty"`   // RFC3339 timestamp for operational/episodic TTL
	Supersedes     []string `json:"supersedes,omitempty"`   // IDs of memories this item replaces
	ContextTier    string   `json:"context_tier,omitempty"` // "L0", "L1", "L2" context stack hint
	Confidence     float64  `json:"confidence,omitempty"`   // 0.0..1.0 for bootstrap/import/inferred items
	CurationStatus string   `json:"curation_status,omitempty"`
	// CurationRule records WHY curation_status was set ("quality" or
	// "never_used"), so the lift conditions don't conflict: a quality demotion
	// lifts when the score recovers; a never_used demotion lifts when the
	// memory is finally used. INVARIANT: must be cleared together with
	// CurationStatus — never one without the other (RecurateMetadata is the
	// canonical writer for both).
	CurationRule string `json:"curation_rule,omitempty"`
	// ScorerVersion records which ScoreQuality formula last curated this memory.
	// Drives re-curation: a value below QualityScorerVersion means stale. Also
	// acts as the "has been scored" marker so a legitimate quality_score of 0
	// (omitempty would otherwise drop it) does not look like an unscored memory.
	ScorerVersion int `json:"scorer_version,omitempty"`

	// Usage-feedback fields (Feature D). InjectedCount/LastInjectedAt are
	// written by the UserPromptSubmit hook when a memory is put in front of
	// the model; UsedCount/LastUsedAt by the Stop hook when the turn's text
	// actually drew on it. RecurateMetadata consumes the pair to demote
	// always-injected-never-used memories.
	InjectedCount  int    `json:"injected_count,omitempty"`
	UsedCount      int    `json:"used_count,omitempty"`
	LastInjectedAt string `json:"last_injected_at,omitempty"`
	LastUsedAt     string `json:"last_used_at,omitempty"`

	// Extra preserves unknown metadata keys from raw maps that are not
	// represented in this struct. Not serialized directly; merged during
	// MarshalJSON and ToAny.
	Extra map[string]any `json:"-"`
}

MemoryMetadata provides structured metadata for memories. Stored as JSON in the Memory.Metadata field (which is `any` for backward compat).

func BootstrapMetadata added in v0.5.0

func BootstrapMetadata(confidence float64) MemoryMetadata

func HandoffMetadata added in v0.5.0

func HandoffMetadata(scope, expiresAt string) MemoryMetadata

func InferDefaultsFromCategory added in v0.5.0

func InferDefaultsFromCategory(category string, hasProject bool) MemoryMetadata

InferDefaultsFromCategory returns a MemoryMetadata with default v2 lifecycle fields inferred from the given category. This is used when no v2 metadata is present on a memory.

func ParseMetadata added in v0.2.0

func ParseMetadata(v any) MemoryMetadata

ParseMetadata parses an `any` (from Memory.Metadata) into MemoryMetadata. Returns zero-value MemoryMetadata if input is nil or unparseable. Unknown keys from raw maps are preserved in the Extra field.

func ParseMetadataFromJSON added in v0.5.0

func ParseMetadataFromJSON(jsonStr string) MemoryMetadata

func PreCompactMetadata added in v0.5.0

func PreCompactMetadata(scope, expiresAt string) MemoryMetadata

func RecurateMetadata added in v0.5.8

func RecurateMetadata(m MemoryMetadata, content, category string, hasProject bool, threshold float64) (MemoryMetadata, bool)

RecurateMetadata is the single canonical pass that refreshes the quality lifecycle fields (quality_score, importance, curation_status, scorer_version) for a memory. It is shared by the save path (ApplyQualityMetadata), the serve-time worker, and the `curation` CLI so the three never diverge.

It is intentionally non-destructive: importance is only initialized when unset (never ratcheted down toward the mechanical quality score), and only the lifecycle fields above are touched. The returned bool reports whether any field actually changed, so callers can skip no-op writes.

func (MemoryMetadata) IsExpired added in v0.5.0

func (m MemoryMetadata) IsExpired(now time.Time) bool

IsExpired returns true if ExpiresAt is set and before the given time. Returns false if ExpiresAt is empty or unparseable.

func (MemoryMetadata) IsOperational added in v0.5.0

func (m MemoryMetadata) IsOperational() bool

func (MemoryMetadata) IsRemoteSyncCandidate added in v0.5.0

func (m MemoryMetadata) IsRemoteSyncCandidate() bool

IsRemoteSyncCandidate returns true when this memory is safe to push to a shared remote. Uses v2 metadata when available; conservative when absent.

func (MemoryMetadata) IsSemantic added in v0.5.0

func (m MemoryMetadata) IsSemantic() bool

func (MemoryMetadata) MarshalJSON added in v0.2.0

func (m MemoryMetadata) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler using an alias to avoid infinite recursion. Merges Extra keys into the JSON output.

func (MemoryMetadata) ToAny added in v0.2.0

func (m MemoryMetadata) ToAny() any

ToAny converts MemoryMetadata to the `any` type expected by Memory.Metadata. Returns nil when all fields are zero.

type MemoryObserver added in v0.5.0

type MemoryObserver interface {
	OnMemorySaved(ctx context.Context, m Memory)
	OnMemoryUpdated(ctx context.Context, m Memory)
	OnMemoryDeleted(ctx context.Context, id string, projectID *string)
}

type ONNXEmbedder

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

func NewONNXEmbedder

func NewONNXEmbedder(modelDir string, logger *slog.Logger) (*ONNXEmbedder, error)

func (*ONNXEmbedder) Close

func (e *ONNXEmbedder) Close() error

func (*ONNXEmbedder) Dimensions

func (e *ONNXEmbedder) Dimensions() int

func (*ONNXEmbedder) Embed

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

func (*ONNXEmbedder) Model

func (e *ONNXEmbedder) Model() string

func (*ONNXEmbedder) Name

func (e *ONNXEmbedder) Name() string

type ONNXPaths

type ONNXPaths struct {
	RuntimeLib    string
	ModelFile     string
	VocabFile     string
	TokenizerFile string
}

type QuantizedEmbedding

type QuantizedEmbedding struct {
	Data   []uint8
	Scale  float32
	MinVal float32
	Dims   int
}

func QuantizeFloat32

func QuantizeFloat32(vec []float32) QuantizedEmbedding

func (QuantizedEmbedding) CosineSimilarity

func (q QuantizedEmbedding) CosineSimilarity(query []float32, queryNorm float64) float64

func (QuantizedEmbedding) CosineWithNorm added in v0.7.3

func (q QuantizedEmbedding) CosineWithNorm(query []float32, queryNorm, storedNorm float64) float64

CosineWithNorm is CosineSimilarity with the stored vector's norm (sqrt(NormSq)) supplied by the caller, avoiding the per-call norm recomputation. Returns bit-identical results to CosineSimilarity.

func (QuantizedEmbedding) Dequantize

func (q QuantizedEmbedding) Dequantize() []float32

func (QuantizedEmbedding) DotProduct

func (q QuantizedEmbedding) DotProduct(query []float32) float64

func (QuantizedEmbedding) MarshalBinary

func (q QuantizedEmbedding) MarshalBinary() ([]byte, error)

func (QuantizedEmbedding) NormSq added in v0.7.3

func (q QuantizedEmbedding) NormSq() float64

NormSq returns the squared L2 norm of the stored vector in dequantized space. It is invariant per stored vector, so callers that score the same vector against many queries precompute sqrt(NormSq) once instead of recomputing the sumD2/sumD loop on every CosineSimilarity call.

func (*QuantizedEmbedding) UnmarshalBinary

func (q *QuantizedEmbedding) UnmarshalBinary(data []byte) error

type SQLiteStore

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

func NewSQLiteStore

func NewSQLiteStore(dbPath string, logger *slog.Logger) (*SQLiteStore, error)

func (*SQLiteStore) BackfillContentHash added in v0.2.0

func (s *SQLiteStore) BackfillContentHash(ctx context.Context) (int, error)

func (*SQLiteStore) Close

func (s *SQLiteStore) Close() error

func (*SQLiteStore) CountWithoutEmbedding added in v0.2.0

func (s *SQLiteStore) CountWithoutEmbedding(ctx context.Context) (int, error)

func (*SQLiteStore) CreateImport added in v0.2.0

func (s *SQLiteStore) CreateImport(id, source, path string) error

func (*SQLiteStore) DB

func (s *SQLiteStore) DB() *sql.DB

func (*SQLiteStore) Delete

func (s *SQLiteStore) Delete(ctx context.Context, id string) error

func (*SQLiteStore) DeleteByScope added in v0.2.0

func (s *SQLiteStore) DeleteByScope(ctx context.Context, opts DeleteScopeOptions) (int, error)

func (*SQLiteStore) FindByContentHash added in v0.2.0

func (s *SQLiteStore) FindByContentHash(ctx context.Context, hash string, projectID *string) (*Memory, error)

func (*SQLiteStore) Get

func (s *SQLiteStore) Get(ctx context.Context, id string) (*Memory, error)

func (*SQLiteStore) GetLastImport added in v0.2.0

func (s *SQLiteStore) GetLastImport(source string) (*ImportRecord, error)

func (*SQLiteStore) List

func (s *SQLiteStore) List(ctx context.Context, opts ListOptions) ([]Memory, error)

func (*SQLiteStore) ListWithoutEmbedding added in v0.2.0

func (s *SQLiteStore) ListWithoutEmbedding(ctx context.Context, limit int) ([]Memory, error)

func (*SQLiteStore) Save

func (s *SQLiteStore) Save(ctx context.Context, m Memory) error

func (*SQLiteStore) Search

func (s *SQLiteStore) Search(ctx context.Context, query string, opts SearchOptions) ([]SearchResult, error)

func (*SQLiteStore) SoftDelete added in v0.2.0

func (s *SQLiteStore) SoftDelete(ctx context.Context, id string) error

func (*SQLiteStore) Stats

func (s *SQLiteStore) Stats(ctx context.Context) (*StoreStats, error)

func (*SQLiteStore) Update added in v0.2.0

func (s *SQLiteStore) Update(ctx context.Context, id string, content string, category string) error

func (*SQLiteStore) UpdateEmbedding added in v0.2.0

func (s *SQLiteStore) UpdateEmbedding(ctx context.Context, id string, embedding []float32) error

func (*SQLiteStore) UpdateImport added in v0.2.0

func (s *SQLiteStore) UpdateImport(id, status string, memoriesImported int, errMsg string) error

func (*SQLiteStore) UpdateMetadata added in v0.5.5

func (s *SQLiteStore) UpdateMetadata(ctx context.Context, id string, metadata any) error

func (*SQLiteStore) VectorCache added in v0.2.0

func (s *SQLiteStore) VectorCache() *VectorCache

type Sanitizer

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

func NewSanitizer

func NewSanitizer(cfg config.SanitizerConfig) *Sanitizer

func (*Sanitizer) Sanitize

func (s *Sanitizer) Sanitize(text string) string

type SaveOptions added in v0.2.0

type SaveOptions struct {
	Content   string
	Category  string
	Source    string
	SourceID  *string
	CWD       string
	SkipEmbed bool
	// PreferenceScope is used only when Category is "preference".
	// Empty defaults to "user" so inferred preferences remain local/personal by default.
	PreferenceScope string
	// Metadata overrides the auto-generated metadata for this save.
	// When non-nil, takes precedence over WithPreferenceScope logic.
	// Callers should construct MemoryMetadata and call ToAny(), or use
	// the HandoffMetadata helper for handoff snapshots.
	Metadata any
}

type ScoredID added in v0.7.3

type ScoredID struct {
	ID    string
	Score float64
}

ScoredID is one scored cache entry returned by Score.

type SearchOptions

type SearchOptions struct {
	MaxResults     int
	Category       string
	ProjectID      string
	BoostProjectID string // Project to boost in results (separate from filter)
	Since          *time.Time
	// WorkingSet, when set, boosts results overlapping the session's current
	// focus (files/symbols/entities). Nil disables the boost.
	WorkingSet *WorkingSetSignals
	// ExplainSignals populates SearchResult.Signals with ranking rationale.
	ExplainSignals bool
}

type SearchResult

type SearchResult struct {
	Memory Memory
	Score  float64
	// Signals explains why a result ranked where it did (e.g. "project",
	// "working_set", "pinned", "fresh", "low_signal"). Populated only when
	// SearchOptions.ExplainSignals is set; nil otherwise.
	Signals []string `json:"signals,omitempty"`
}

type Service

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

func NewService

func NewService(cfg *config.Config, logger *slog.Logger) (*Service, error)

func (*Service) BackfillContentHash added in v0.2.0

func (s *Service) BackfillContentHash(ctx context.Context) (int, error)

func (*Service) BackfillEmbeddings added in v0.2.0

func (s *Service) BackfillEmbeddings(ctx context.Context, batchSize int) (int, error)

BackfillEmbeddings embeds every memory still missing a vector, as fast as the machine allows (no pause between batches). Used by the one-shot `import` command where blocking-until-done is the desired behavior.

func (*Service) BackfillEmbeddingsThrottled added in v0.8.9

func (s *Service) BackfillEmbeddingsThrottled(ctx context.Context, batchSize int, pause time.Duration) (int, error)

BackfillEmbeddingsThrottled is the same backfill but sleeps `pause` between batches so a long historical backfill on a user's machine stays gentle on the CPU instead of pinning a core. It honors ctx cancellation between batches and between items, so a serve shutdown stops it promptly. Idempotent and resumable: it drains ListWithoutEmbedding, so re-running after an interrupted pass just continues where it left off.

func (*Service) Close

func (s *Service) Close()

func (*Service) EmbeddingsEnabled added in v0.8.9

func (s *Service) EmbeddingsEnabled() bool

EmbeddingsEnabled reports whether vector embedding is available (provider loaded + cache present). Callers use it to skip embedding-only background work (e.g. the serve-time backfill) instead of looping on a guaranteed error.

func (*Service) Forget

func (s *Service) Forget(ctx context.Context, id string) error

func (*Service) ForgetByScope added in v0.2.0

func (s *Service) ForgetByScope(ctx context.Context, projectID, category, source string, hard bool) (int, error)

func (*Service) Get

func (s *Service) Get(ctx context.Context, id string) (*Memory, error)

func (*Service) List

func (s *Service) List(ctx context.Context, opts ListOptions) ([]Memory, error)

func (*Service) RegisterObserver added in v0.5.0

func (s *Service) RegisterObserver(obs MemoryObserver)

func (*Service) ResolveProject added in v0.2.0

func (s *Service) ResolveProject(cwd string) string

ResolveProject returns the project ID for a given working directory, or empty string if none.

func (*Service) ResolveProjectInfo added in v0.5.9

func (s *Service) ResolveProjectInfo(cwd string) (*project.Project, error)

ResolveProjectInfo returns the full project for a working directory (ID, Name and git-origin RemoteKey), or nil when cwd is not inside a git repo. Repo-scoped sync uses RemoteKey to identify a repository independent of its local directory name.

func (*Service) Save

func (s *Service) Save(ctx context.Context, content, category, source string, cwd string) (*Memory, error)

func (*Service) SaveMemory added in v0.1.1

func (s *Service) SaveMemory(ctx context.Context, content, category, source string, cwd string) error

func (*Service) SaveRaw added in v0.1.6

func (s *Service) SaveRaw(ctx context.Context, content, category, source string, cwd string) error

func (*Service) SaveRawNoEmbed added in v0.2.0

func (s *Service) SaveRawNoEmbed(ctx context.Context, content, category, source string, cwd string) error

func (*Service) SaveWithOptions added in v0.2.0

func (s *Service) SaveWithOptions(ctx context.Context, opts SaveOptions) (*Memory, error)

func (*Service) Search

func (s *Service) Search(ctx context.Context, query string, opts SearchOptions) ([]SearchResult, error)

func (*Service) SetKGExtractor added in v0.2.0

func (s *Service) SetKGExtractor(extractor *kg.PatternExtractor)

func (*Service) SoftForget added in v0.2.0

func (s *Service) SoftForget(ctx context.Context, id string) error

func (*Service) Stats

func (s *Service) Stats(ctx context.Context) (*StoreStats, error)

func (*Service) StoreDB

func (s *Service) StoreDB() *sql.DB

func (*Service) Update added in v0.2.0

func (s *Service) Update(ctx context.Context, id, content, category string) (*Memory, error)

func (*Service) UpdateMetadata added in v0.5.5

func (s *Service) UpdateMetadata(ctx context.Context, id string, metadata any) error

func (*Service) VectorCache added in v0.2.0

func (s *Service) VectorCache() *VectorCache

type Store

type Store interface {
	Save(ctx context.Context, m Memory) error
	Get(ctx context.Context, id string) (*Memory, error)
	Update(ctx context.Context, id, content, category string) error
	UpdateMetadata(ctx context.Context, id string, metadata any) error
	Search(ctx context.Context, query string, opts SearchOptions) ([]SearchResult, error)
	Delete(ctx context.Context, id string) error
	SoftDelete(ctx context.Context, id string) error
	DeleteByScope(ctx context.Context, opts DeleteScopeOptions) (int, error)
	List(ctx context.Context, opts ListOptions) ([]Memory, error)
	Stats(ctx context.Context) (*StoreStats, error)
	UpdateEmbedding(ctx context.Context, id string, embedding []float32) error
	ListWithoutEmbedding(ctx context.Context, limit int) ([]Memory, error)
	FindByContentHash(ctx context.Context, hash string, projectID *string) (*Memory, error)
	BackfillContentHash(ctx context.Context) (int, error)
	DB() *sql.DB
	VectorCache() *VectorCache
	Close() error
}

type StoreStats

type StoreStats struct {
	TotalMemories int            `json:"total_memories"`
	ByCategory    map[string]int `json:"by_category"`
	ByProject     map[string]int `json:"by_project"`
}

type Tokenizer added in v0.2.0

type Tokenizer interface {
	Tokenize(text string) (inputIDs, attentionMask, tokenTypeIDs []int64)
}

Tokenizer converts text into ONNX-compatible token sequences.

type TopicChangeDetector added in v0.2.0

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

func NewTopicChangeDetector added in v0.2.0

func NewTopicChangeDetector(embedder EmbeddingProvider, entityDetector *EntityDetector) *TopicChangeDetector

func (*TopicChangeDetector) Check added in v0.2.0

func (d *TopicChangeDetector) Check(ctx context.Context, currentQuery string) (changed bool, err error)

func (*TopicChangeDetector) Reset added in v0.2.0

func (d *TopicChangeDetector) Reset()

type VectorCache added in v0.2.0

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

VectorCache is a thread-safe in-memory cache of memory embeddings keyed by memory ID.

func NewVectorCache added in v0.2.0

func NewVectorCache(logger *slog.Logger) *VectorCache

func (*VectorCache) All added in v0.2.0

func (c *VectorCache) All() map[string][]float32

func (*VectorCache) Get added in v0.2.0

func (c *VectorCache) Get(id string) ([]float32, bool)

func (*VectorCache) Len added in v0.2.0

func (c *VectorCache) Len() int

func (*VectorCache) Load added in v0.2.0

func (c *VectorCache) Load(db *sql.DB) error

func (*VectorCache) Put added in v0.2.0

func (c *VectorCache) Put(id string, embedding []float32)

func (*VectorCache) Remove added in v0.2.0

func (c *VectorCache) Remove(id string)

func (*VectorCache) Score added in v0.7.3

func (c *VectorCache) Score(query []float32, queryNorm, minScore float64, topK int) []ScoredID

Score scans the cache once under a read lock — without copying the map — scoring every entry against the query via the memoized quantized form and norm, and returns the top-k entries scoring above minScore. This replaces a per-query All() copy + re-quantize + re-norm with a single allocation-light pass; scores are bit-identical to QuantizedEmbedding.CosineSimilarity.

type WordPieceTokenizer

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

func NewWordPieceTokenizer

func NewWordPieceTokenizer(vocabPath string, maxLen int) (*WordPieceTokenizer, error)

func (*WordPieceTokenizer) Tokenize

func (t *WordPieceTokenizer) Tokenize(text string) (inputIDs, attentionMask, tokenTypeIDs []int64)

type WorkingSetSignals added in v0.7.2

type WorkingSetSignals struct {
	Files    []string
	Symbols  []string
	Entities []string
}

WorkingSetSignals is the retrieval-relevant projection of a session working set: the files/symbols/entities currently in focus. Memories whose content or keywords overlap these get a working-set boost. Kept dependency-free here so pkg/memory never imports pkg/session.

func (*WorkingSetSignals) Empty added in v0.7.2

func (w *WorkingSetSignals) Empty() bool

Empty reports whether there are no focus tokens to boost on.

Jump to

Keyboard shortcuts

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