Documentation
¶
Overview ¶
Package memory provides cross-session memory persistence as a set of typed, single-fact files with a lightweight frontmatter header.
Facts live in two scopes:
- global (~/.config/moa/global/memory/<slug>.md) — cross-project
- project (~/.config/moa/codebases/<key>/memory/<slug>.md) — this repository
where <key> is core.CodebaseKey(workspaceRoot): the identity of the repository the workspace belongs to, so every git worktree of one repo reads and writes the same facts and deleting a worktree no longer orphans what was learned in it. Only the index (one line per fact) is injected into the prompt; full bodies are read on demand. The index is derived from the files at load — moa never writes a MEMORY.md of its own.
Index ¶
- Constants
- func ValidName(name string) bool
- func ValidType(t Type) bool
- type IndexStatus
- type Lifecycle
- type Memory
- type Scope
- type SearchHit
- type SearchOptions
- type SearchResult
- type Store
- func (s *Store) Delete(id string) error
- func (s *Store) FormatIndex(mems []Memory) string
- func (s *Store) GlobalDir() string
- func (s *Store) List() []Memory
- func (s *Store) Migrate() error
- func (s *Store) MigrateV1IfNeeded() error
- func (s *Store) ProjectDir() string
- func (s *Store) Read(id string) (Memory, bool, error)
- func (s *Store) Search(opts SearchOptions) (SearchResult, error)
- func (s *Store) Write(m Memory) (string, error)
- type Type
Constants ¶
const ( // MaxFactSize is the hard per-fact limit (16KB). MaxFactSize = 16 * 1024 // MaxDescriptionBytes caps the one-line hook at write time. The // description is the only part of a fact paid for on every turn, so a long // one taxes every session; detail belongs in the body. MaxDescriptionBytes = 180 )
const ( // SnippetBytes bounds the excerpt returned per hit. Search exists so the // agent can find a fact without paying for its body: it returns where the // match is, never the fact itself. SnippetBytes = 240 // DefaultSearchLimit / MaxSearchLimit bound how many hits come back. DefaultSearchLimit = 10 MaxSearchLimit = 25 )
Variables ¶
This section is empty.
Functions ¶
Types ¶
type IndexStatus ¶ added in v0.30.0
type IndexStatus struct {
UsedBytes int
BudgetBytes int
Facts int
Dropped int
DroppedProject int
DroppedGlobal int
// contains filtered or unexported fields
}
IndexStatus reports how much of the prompt index budget a fact set uses and how many facts do not fit. It is the same computation FormatIndex performs (including the two-way roll-over), exposed so a write can tell the agent that what it just saved may never reach the prompt.
func IndexStatusOf ¶ added in v0.30.0
func IndexStatusOf(mems []Memory) IndexStatus
IndexStatusOf renders the index for mems and measures it.
type Lifecycle ¶ added in v0.30.0
type Lifecycle int
Lifecycle is a fact's declared expiry contract. It replaces an inferred bool: "no invalidate_when" used to mean durable, which silently promoted every pre-lifecycle file to permanent instead of admitting that it never declared anything.
const ( // LifecycleLegacy is a file written before lifecycles existed: it declares // neither `durable: true` nor `invalidate_when`. Readable, but a write // must upgrade it to one of the other two. LifecycleLegacy Lifecycle = iota // LifecycleDurable is an explicit `durable: true`. LifecycleDurable // LifecycleConditional carries a checkable `invalidate_when` condition. LifecycleConditional )
type Memory ¶
type Memory struct {
Name string
Description string
Type Type // legacy routing field, preserved when compatible with Scope
InvalidateWhen string
Lifecycle Lifecycle
Body string
Scope Scope
Path string // absolute path to the file (set on read/list)
}
Memory is a single fact.
type Scope ¶
type Scope int
Scope is where a fact lives.
func ParseScope ¶ added in v0.30.0
ParseScope maps the tool-facing scope name to a Scope.
func ScopeForType ¶
ScopeForType routes a legacy type to its scope (D2): user/feedback are global, everything else is project-local. Only reachable through old files.
type SearchHit ¶ added in v0.30.0
SearchHit is one matching fact with a bounded excerpt around the match.
type SearchOptions ¶ added in v0.30.0
type SearchOptions struct {
Query string
Regex bool // treat Query as an RE2 pattern instead of a literal substring
Limit int
Offset int
}
SearchOptions parameterizes Search.
type SearchResult ¶ added in v0.30.0
SearchResult is a page of hits plus the total, so the caller can tell the agent how to ask for the rest.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store manages the global and project memory directories for one workspace.
func New ¶
New builds a Store. configDir is the moa config root (~/.config/moa); workspaceRoot selects the project scope.
It does not migrate anything: call Migrate for that, once, at startup.
func (*Store) FormatIndex ¶
FormatIndex renders the index as one bullet per fact (no framing — the caller adds it). Empty if no facts. Bounded by maxIndexBytes with a truncation note.
func (*Store) List ¶
List scans both scopes and returns all facts, project scope first, then by name. Global and project facts with the same name coexist as distinct IDs.
func (*Store) Migrate ¶ added in v0.25.0
Migrate brings this store's project scope up to date. Call it once, at startup, before reading anything.
func (*Store) MigrateV1IfNeeded ¶
MigrateV1IfNeeded wraps a flat v1 MEMORY.md into a single legacy fact, then retires the flat file. Idempotent even across partial failures: the flat file is only renamed after the fact is safely written, so an interrupted run simply retries next time (D6).
The flat file is looked for under the path-keyed project directory because that is the only place v1 ever wrote it; the fact it becomes is written to the current (codebase-keyed) directory like any other. It must therefore run at startup — see Migrate.
func (*Store) ProjectDir ¶
ProjectDir returns this workspace's project memory directory.
func (*Store) Read ¶
Read returns the full fact for a canonical ID ("project/foo", "global/foo") or a bare name. A bare name that exists in both scopes is an error (D9).
func (*Store) Search ¶ added in v0.30.0
func (s *Store) Search(opts SearchOptions) (SearchResult, error)
Search does a lexical search over name, description and body in both scopes. Matching is case-insensitive substring by default, or RE2 when opts.Regex is set; an uncompilable pattern is an error rather than a silent zero-result.
type Type ¶
type Type string
Type is the legacy fact classification. The four-value taxonomy existed only to pick one of two scopes, so `scope:` is the source of truth. `type:` is still written for interoperability with older binaries that route files by it, and an existing compatible value is preserved on rewrite.