memory

package
v0.0.0-...-75696bf Latest Latest
Warning

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

Go to latest
Published: Oct 13, 2026 License: Apache-2.0 Imports: 46 Imported by: 0

Documentation

Index

Constants

View Source
const (
	HorizonWorking = "working"
	HorizonShort   = "short"
	HorizonMedium  = "medium"
	HorizonLong    = "long"
)
View Source
const (
	KindPrompt      = "prompt"
	KindTool        = "tool"
	KindWorking     = "working"
	KindSession     = "session"
	KindPin         = "pin"
	KindTeaching    = "teaching"
	KindObservation = "observation"

	SourceSpan     = "span"
	SourceAgent    = "agent"
	SourceTeach    = "teach"
	SourceHeadless = "headless"
	SourceObserver = "observer"

	// ObservationType* taxonomy values stored on topic.
	ObservationDecision  = "decision"
	ObservationBugfix    = "bugfix"
	ObservationFeature   = "feature"
	ObservationRefactor  = "refactor"
	ObservationDiscovery = "discovery"
	ObservationChange    = "change"

	EdgeContradicts  = "contradicts"
	EdgeSameSession  = "same_session"
	EdgeRolledUpFrom = "rolled_up_from"
	EdgeTaughtFrom   = "taught_from"
	EdgeNext         = "next"
)
View Source
const DefaultEmbedListen = "127.0.0.1:18765"

DefaultEmbedListen is the shared loopback the UI and CLI probe.

View Source
const EmbedderID = "so-prose-384-v1"

EmbedderID stamps hashed 384-d int8 vectors used when the loopback worker is unavailable. Neural workers use distinct ids so geometries are never mixed.

Variables

This section is empty.

Functions

func ClippedBodyHint

func ClippedBodyHint(hits []Hit) string

ClippedBodyHint tells the agent recall bodies are windows, not the full episode.

func CompactSnapshot

func CompactSnapshot(root, sessionID string) string

CompactSnapshot is the Cursor preCompact inject: this-session working set, fail-open, never a full JSONL dump.

func ConsolidateCap

func ConsolidateCap() int

func CopyInto

func CopyInto(srcPath, dstPath string) error

CopyInto copies memory tables from srcPath into dstPath. Graph publish replaces so.db with a staged graph; this keeps the project diary. No-op if src is missing or has no memory_episodes table.

func Cosine

func Cosine(left Vector, right []byte) float64

func CountLiveMemories

func CountLiveMemories(root string) int

CountLiveMemories is fail-open for hooks.

func CurrentEmbedder

func CurrentEmbedder() string

func DefaultHorizon

func DefaultHorizon(kind string, pin bool) string

func DisplayType

func DisplayType(ep Episode) string

func DistillBrief

func DistillBrief(root, sessionID string) (string, error)

DistillBrief is the same prompt the one-shot CLI would see, for the live agent.

func EmptyHitHint

func EmptyHitHint(live, fts int, sealed bool) string

EmptyHitHint distinguishes empty store vs no match vs sealed FTS (AXI hint:).

func EmptyRecallHint

func EmptyRecallHint(live, fts int, sealed bool) string

EmptyRecallHint is the empty-hit line for so memory recall (which prints bodies).

func EnsureEmbedWorker

func EnsureEmbedWorker()

EnsureEmbedWorker points capture/recall at the shared loopback worker. Users do not set SO_EMBED_URL for the normal path; that env remains an override.

func EnsureModelDir

func EnsureModelDir() error

func EstimateTokens

func EstimateTokens(s string) int

func FetchModels

func FetchModels() error

func FormatIndexLine

func FormatIndexLine(ep Episode) string

func HasEpisodes

func HasEpisodes(root string) bool

HasEpisodes is true when this repository's store already has at least one memory moment or rollup. Used to keep cold-clone tool lists graph-only.

func HelpForGet

func HelpForGet(eps []Episode) []string

func HelpForSearch

func HelpForSearch(hits []Hit) []string

func IndexRow

func IndexRow(idx IndexHit) map[string]any

IndexRow is a 4-column AXI list row for search/last/timeline.

func IndexRowsFromEpisodes

func IndexRowsFromEpisodes(eps []Episode) []map[string]any

func IndexRowsFromHits

func IndexRowsFromHits(hits []Hit) []map[string]any

func LiveDistillInstruction

func LiveDistillInstruction(pendingSession string) string

func ModelDir

func ModelDir() string

func NormalizeHorizon

func NormalizeHorizon(raw string) string

func NormalizePath

func NormalizePath(p string) string

NormalizePath slash-normalizes episode file paths so FTS and --file filters match Windows and POSIX spellings of the same location.

func ParseIDs

func ParseIDs(args []string) ([]int64, error)

func PendingDistillLine

func PendingDistillLine(root string) string

func PromptRecallPack

func PromptRecallPack(root, cue string) string

PromptRecallPack is the UserPromptSubmit inject for a prior-work / personal cue: matching recalled bodies from this workspace store, framed as the user's own notes. Empty when recall has no hits (caller may fall back to the pointer-only index). Fail-open.

func Sanitize

func Sanitize(s string) string

Sanitize strips <private> blocks and secrets. Empty after privacy tags means the moment must not be stored or sent to a distill prompt.

func ServeEmbedWorker

func ServeEmbedWorker(addr string) error

func SessionStartIndex

func SessionStartIndex(root string) string

SessionStartIndex is the SessionStart inject: when live memories exist, say how many and give the Bash recall command. Fail-open, no bodies and no uncued #id list (there is no question yet). Prompt-submit uses PromptRecallPack for matching bodies. Empty store stays silent except a pending distill one-liner.

func SleepRoot

func SleepRoot(root string) error

Types

type ActivityBucket

type ActivityBucket struct {
	Day   string `json:"day"`
	Count int    `json:"count"`
}

type CaptureInput

type CaptureInput struct {
	SessionID        string
	Kind             string
	Source           string
	Title            string
	Text             string
	Files            []string
	ToolName         string
	ContradictOf     int64
	Pin              bool
	Topic            string
	Facts            []string
	Narrative        string
	Concepts         []string
	Horizon          string
	KeepUntilSession int
}

type DistillResult

type DistillResult struct {
	SessionID string `json:"session_id"`
	Provider  string `json:"provider,omitempty"`
	Pending   bool   `json:"pending,omitempty"`
	Skipped   string `json:"skipped,omitempty"`
	EpisodeID int64  `json:"episode_id,omitempty"`
	Written   int    `json:"written,omitempty"`
}

func ApplyJSON

func ApplyJSON(root, sessionID string, raw []byte) DistillResult

ApplyJSON ingests live-agent distill JSON without spawning a headless CLI.

func Distill

func Distill(root, sessionID string) DistillResult

Distill runs skip gates then at most one bounded call on the session's own CLI.

func DistillSession

func DistillSession(root, sessionID string) (DistillResult, error)

func MaybeDistill

func MaybeDistill(root, sessionID string, detach bool) DistillResult

MaybeDistill detaches `so memory distill` after finalize when the live vendor has a one-shot CLI. Cursor marks pending for SessionStart.

type Economy

type Economy struct {
	PacksServed      int    `json:"packs_served"`
	TokensInjected   int    `json:"tokens_injected"`
	FallbackSearches int    `json:"fallback_searches"`
	TokensSaved      int    `json:"tokens_saved"`
	UpdatedAt        string `json:"updated_at,omitempty"`
}

type Episode

type Episode struct {
	ID               int64    `json:"id"`
	UID              string   `json:"uid"`
	SessionID        string   `json:"session_id,omitempty"`
	SpanID           string   `json:"span_id,omitempty"`
	Kind             string   `json:"kind"`
	Source           string   `json:"source"`
	Title            string   `json:"title"`
	Text             string   `json:"text,omitempty"`
	Files            []string `json:"files,omitempty"`
	ToolName         string   `json:"tool_name,omitempty"`
	Tokens           int      `json:"tokens"`
	Pinned           bool     `json:"pinned"`
	Faded            bool     `json:"faded"`
	Fading           bool     `json:"fading,omitempty"`
	EmbeddingPending bool     `json:"embedding_pending,omitempty"`
	CreatedAt        string   `json:"created_at"`
	UpdatedAt        string   `json:"updated_at"`
	ValidFrom        string   `json:"valid_from,omitempty"`
	ValidTo          string   `json:"valid_to,omitempty"`
	CommunityID      string   `json:"community_id,omitempty"`
	Centrality       float64  `json:"centrality,omitempty"`
	Tier             string   `json:"tier,omitempty"`
	Horizon          string   `json:"horizon,omitempty"`
	KeepUntilSession int      `json:"keep_until_session,omitempty"`
	NeverDecay       bool     `json:"never_decay,omitempty"`
	Tags             string   `json:"tags,omitempty"`
	Topic            string   `json:"topic,omitempty"`
	Facts            []string `json:"facts,omitempty"`
	Narrative        string   `json:"narrative,omitempty"`
	Concepts         []string `json:"concepts,omitempty"`
	ContentHash      string   `json:"content_hash,omitempty"`
	Score            float64  `json:"score,omitempty"`
}

func CaptureRoot

func CaptureRoot(root string, in CaptureInput) (Episode, error)

func TeachFile

func TeachFile(root, path, title string) (Episode, error)

func TeachText

func TeachText(root, title, text string) (Episode, error)

type Hit

type Hit struct {
	Episode
	Snippet string `json:"snippet,omitempty"`
}

type IndexHit

type IndexHit struct {
	ID        int64    `json:"id"`
	Kind      string   `json:"kind"`
	Topic     string   `json:"topic,omitempty"`
	Horizon   string   `json:"horizon,omitempty"`
	Title     string   `json:"title"`
	Tokens    int      `json:"tokens"`
	Score     float64  `json:"score,omitempty"`
	SessionID string   `json:"session_id,omitempty"`
	Files     []string `json:"files,omitempty"`
}

IndexHit is the cheap search/timeline row: IDs, type, title, tokens. Bodies stay behind so memory get (index-then-fetch pattern).

func IndexFromEpisode

func IndexFromEpisode(ep Episode) IndexHit

func IndexFromHit

func IndexFromHit(h Hit) IndexHit

type IngestResult

type IngestResult struct {
	SessionID string `json:"session_id"`
	Inserted  int    `json:"inserted"`
	Existing  int    `json:"existing"`
	Skipped   int    `json:"skipped"`
}

func IngestAll

func IngestAll(root string) ([]IngestResult, error)

func IngestBackfill

func IngestBackfill(root, currentSession string, limit int) []IngestResult

IngestBackfill ingests at most `limit` recent other sessions that have spans but no KindPrompt. Fail-open. Bound for SessionStart (5s hook).

func IngestSession

func IngestSession(root, sessionID string) (IngestResult, error)

type MemoryCounts

type MemoryCounts struct {
	Episodic   int `json:"episodic"`
	Semantic   int `json:"semantic"`
	Procedural int `json:"procedural"`
	Working    int `json:"working"`
	Short      int `json:"short"`
	Medium     int `json:"medium"`
	Long       int `json:"long"`
	Tombstoned int `json:"tombstoned"`
	Edges      int `json:"edges"`
	Pins       int `json:"pins"`
	Fading     int `json:"fading"`
}

type ObserveResult

type ObserveResult struct {
	SessionID string `json:"session_id"`
	Inserted  int    `json:"inserted"`
	Provider  string `json:"provider,omitempty"`
	Skipped   string `json:"skipped,omitempty"`
}

func ObserveSession

func ObserveSession(root, sessionID string) (ObserveResult, error)

ObserveSession is a no-op. Typed knowledge comes from live capture JSON or post-session distill — not regex on prompts.

type Pack

type Pack struct {
	Text           string `json:"text"`
	Tokens         int    `json:"tokens"`
	PendingSession string `json:"pending_session,omitempty"`
	AskDistill     bool   `json:"ask_distill,omitempty"`
}

func PackForRoot

func PackForRoot(root, cue, currentSession string) (Pack, error)

func PackNextForRoot

func PackNextForRoot(root, cue, currentSession string) (Pack, error)

type RecallResult

type RecallResult struct {
	Hits         []Hit `json:"hits"`
	AntiHits     []Hit `json:"anti_hits"`
	BudgetTokens int   `json:"budget_tokens"`
}

type SearchFilter

type SearchFilter struct {
	Query         string
	Kind          string
	Type          string
	SessionID     string
	File          string
	Limit         int
	IncludeFaded  bool
	RecordEconomy bool
	AsOf          string
	ChangedSince  string
	Horizon       string
	ExcludeKinds  []string
}

type Status

type Status struct {
	Episodes         int              `json:"episodes"`
	Vectors          int              `json:"vectors"`
	Edges            int              `json:"edges"`
	Topics           int              `json:"topics"`
	Teachings        int              `json:"teachings"`
	Pins             int              `json:"pins"`
	Faded            int              `json:"faded"`
	Fading           int              `json:"fading"`
	RolledUp         int              `json:"rolled_up"`
	PendingDistill   []string         `json:"pending_distill"`
	DistillPaused    bool             `json:"distill_paused"`
	EmbedderID       string           `json:"embedder_id"`
	EmbeddingPending int              `json:"embedding_pending"`
	RolledUpPct      float64          `json:"rolled_up_pct"`
	FadePct          float64          `json:"fade_pct"`
	EdgeDensity      float64          `json:"edge_density"`
	Coverage         float64          `json:"coverage"`
	Live             int              `json:"live"`
	Lifecycle        string           `json:"lifecycle"`
	KnowledgePct     float64          `json:"knowledge_pct"`
	Connected        float64          `json:"connected"`
	CleanedPct       float64          `json:"cleaned_pct"`
	Counts           MemoryCounts     `json:"counts"`
	Activity         []ActivityBucket `json:"activity,omitempty"`
	ActivityPeak     int              `json:"activity_peak"`
	Economy          Economy          `json:"economy"`
	SchemaVersion    string           `json:"schema_version"`
	TopicsDetail     []Topic          `json:"topics_detail,omitempty"`
}

type Store

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

func Open

func Open(path string) (*Store, error)

func OpenQuick

func OpenQuick(path string) (*Store, error)

func OpenRoot

func OpenRoot(root string) (*Store, error)

func (*Store) BuildNextPack

func (s *Store) BuildNextPack(cue, currentSession string) (Pack, error)

func (*Store) BuildPack

func (s *Store) BuildPack(cue, currentSession string) (Pack, error)

func (*Store) BuildPromptRecall

func (s *Store) BuildPromptRecall(cue string) string

func (*Store) BuildSessionIndex

func (s *Store) BuildSessionIndex() string

func (*Store) BumpDistillFail

func (s *Store) BumpDistillFail(sessionID string)

func (*Store) BumpSessionSeq

func (s *Store) BumpSessionSeq() int

func (*Store) Capture

func (s *Store) Capture(in CaptureInput) (Episode, error)

func (*Store) ClearDistillFail

func (s *Store) ClearDistillFail(sessionID string)

func (*Store) ClearPending

func (s *Store) ClearPending(sessionID string) error

func (*Store) Close

func (s *Store) Close() error

func (*Store) ClusterTopics

func (s *Store) ClusterTopics() error

func (*Store) Consolidate

func (s *Store) Consolidate() error

func (*Store) Contradict

func (s *Store) Contradict(oldID int64, in CaptureInput) (Episode, error)

func (*Store) Curiosity

func (s *Store) Curiosity(limit int) ([]Hit, error)

func (*Store) DeleteExpired

func (s *Store) DeleteExpired(cutoff time.Time) (int, error)

DeleteExpired hard-deletes unpinned moments older than cutoff. Teachings, pins, and never_decay rows are kept.

func (*Store) DeleteUnprotectedForSessions

func (s *Store) DeleteUnprotectedForSessions(sessionIDs []string) (int, error)

DeleteUnprotectedForSessions removes diary rows tied to deleted session ids. Teachings, pins, and never_decay rows stay.

func (*Store) DistillFailCount

func (s *Store) DistillFailCount(sessionID string) int

func (*Store) DistillPaused

func (s *Store) DistillPaused() bool

func (*Store) DistilledSessions

func (s *Store) DistilledSessions() []string

func (*Store) Events

func (s *Store) Events(limit int) ([]TimelineBucket, error)

func (*Store) ExpireHorizons

func (s *Store) ExpireHorizons() (int, error)

func (*Store) FTSDocCount

func (s *Store) FTSDocCount() int

FTSDocCount is how many plaintext FTS rows exist (0 if missing).

func (*Store) Fade

func (s *Store) Fade(id int64) error

func (*Store) FileContext

func (s *Store) FileContext(path string, limit int) ([]Hit, error)

func (*Store) ForgetEpisode

func (s *Store) ForgetEpisode(id int64) error

func (*Store) Get

func (s *Store) Get(id int64) (Episode, error)

func (*Store) GetMany

func (s *Store) GetMany(ids []int64) ([]Episode, error)

func (*Store) HasDistilled

func (s *Store) HasDistilled(sessionID string) bool

func (*Store) HasKindPrompt

func (s *Store) HasKindPrompt(sessionID string) bool

func (*Store) HasSessionRollup

func (s *Store) HasSessionRollup(sessionID string) bool

func (*Store) IndexSealed

func (s *Store) IndexSealed() bool

IndexSealed reports a leftover ciphertext FTS (search cannot see bodies).

func (*Store) LatestSessionKind

func (s *Store) LatestSessionKind(kind string) (Episode, error)

func (*Store) Layout

func (s *Store) Layout(maxNodes int) (api.LayoutResult, error)

func (*Store) ListTopics

func (s *Store) ListTopics() ([]Topic, error)

func (*Store) LiveKnowledge

func (s *Store) LiveKnowledge(limit int) ([]Episode, error)

func (*Store) LiveMemoryCount

func (s *Store) LiveMemoryCount() int

LiveMemoryCount is faded non-tool, non-prompt rows on knowledge horizons (KindSession diary captures included). KindPrompt is never knowledge (M3).

func (*Store) MapJSON

func (s *Store) MapJSON() (string, error)

func (*Store) MarkDistilled

func (s *Store) MarkDistilled(sessionID string) error

func (*Store) MarkPending

func (s *Store) MarkPending(sessionID string) error

func (*Store) Patterns

func (s *Store) Patterns(limit int) ([]string, error)

func (*Store) PendingDistill

func (s *Store) PendingDistill() []string

func (*Store) Pin

func (s *Store) Pin(id int64) error

func (*Store) Ping

func (s *Store) Ping(ctx context.Context) error

Ping is a cheap health check used by fail-open hook paths.

func (*Store) Preview

func (s *Store) Preview(id int64) string

func (*Store) Profile

func (s *Store) Profile() map[string]string

func (*Store) PromoteHorizon

func (s *Store) PromoteHorizon(id int64, horizon string) error

func (*Store) ReadEconomy

func (s *Store) ReadEconomy() (Economy, error)

func (*Store) Recall

func (s *Store) Recall(query string, budget int) (RecallResult, error)

func (*Store) RecallFilter

func (s *Store) RecallFilter(filter SearchFilter, budget int) (RecallResult, error)

func (*Store) RecallShape

func (s *Store) RecallShape(cue string, limit int) ([]Hit, error)

RecallShape is a compatibility alias for Search. Shape/HD vectors are no longer written or scored; hybrid FTS+dense ranking replaced that path.

func (*Store) Recent

func (s *Store) Recent(limit int) ([]Episode, error)

func (*Store) RecordPack

func (s *Store) RecordPack(tokensInjected, tokensSaved int) error

func (*Store) RecordSearch

func (s *Store) RecordSearch() error

func (*Store) Reinforce

func (s *Store) Reinforce(id int64) error

func (*Store) Rescue

func (s *Store) Rescue(id int64) error

func (*Store) Search

func (s *Store) Search(filter SearchFilter) ([]Hit, error)

func (*Store) SessionSeq

func (s *Store) SessionSeq() int

func (*Store) SetDistillPaused

func (s *Store) SetDistillPaused(paused bool) error

func (*Store) SetProfile

func (s *Store) SetProfile(key, value string) error

func (*Store) Sleep

func (s *Store) Sleep() error

func (*Store) Status

func (s *Store) Status() (Status, error)

func (*Store) TemporalRecall

func (s *Store) TemporalRecall(query, asOf, changedSince string, budget int) (RecallResult, error)

func (*Store) Timeline

func (s *Store) Timeline(limit int) ([]TimelineBucket, error)

func (*Store) TimelineAround

func (s *Store) TimelineAround(id int64, before, after int) ([]Episode, error)

func (*Store) When

func (s *Store) When(query string, limit int) ([]Hit, error)

func (*Store) WorkingSnapshot

func (s *Store) WorkingSnapshot(sessionID string) string

type TeachReport

type TeachReport struct {
	Inserted       int       `json:"inserted"`
	Reinforced     int       `json:"reinforced"`
	Edges          int       `json:"edges"`
	RecallTested   int       `json:"recall_tested"`
	RecallVerified int       `json:"recall_verified"`
	VerifiedDelta  int       `json:"verified_delta"`
	Episodes       []Episode `json:"episodes,omitempty"`
}

func TeachPath

func TeachPath(root, path, title string) (TeachReport, error)

type TimelineBucket

type TimelineBucket struct {
	When  string    `json:"when"`
	Items []Episode `json:"items"`
}

type Topic

type Topic struct {
	ID         int64   `json:"id"`
	Label      string  `json:"label"`
	Community  int     `json:"community"`
	EpisodeIDs []int64 `json:"episode_ids"`
	Size       int     `json:"size"`
	UpdatedAt  string  `json:"updated_at"`
}

type Vector

type Vector [embedDimensions]int8

Vector is a unit-quantized 384-d int8 embedding.

func EmbedQuery

func EmbedQuery(text string) Vector

EmbedQuery encodes a search query. The BGE worker gets input_type=query (instruction prefix). The hash fallback is unprefixed so it stays symmetric with stored document vectors on machines without the Python worker.

func EmbedSentence

func EmbedSentence(text string) Vector

EmbedSentence hashes word and character n-grams into a 384-d int8 unit vector.

func EmbedText

func EmbedText(text string) Vector

EmbedText encodes prose for memory ingest and recall. A healthy BGE worker is preferred. If one is configured but fails, a zero vector (embedding_pending) is returned so hash geometry is never mixed into a neural store. If no worker is configured at all, hashed embeddings are used and EnsureEmbedWorker prints a one-time stderr notice — that path is weaker semantic recall, not a silent success.

func (Vector) Bytes

func (v Vector) Bytes() []byte

type WatchResult

type WatchResult struct {
	Taught TeachReport `json:"taught"`
	Faded  []int64     `json:"faded,omitempty"`
}

func WatchOnce

func WatchOnce(root, dir string) (WatchResult, error)

Jump to

Keyboard shortcuts

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