Documentation
¶
Overview ¶
Package memmy is the embeddable library facade for the memmy LLM memory system. It is the only stable public surface; everything below it lives under internal/ and may change without notice.
Typical use:
emb := memmy.NewFakeEmbedder(64) // or NewGeminiEmbedder(ctx, opts)
svc, closer, err := memmy.Open(ctx, memmy.Options{
Neo4j: memmy.Neo4jOptions{
URI: "bolt://localhost:7687",
User: "neo4j",
Password: os.Getenv("NEO4J_PASSWORD"),
},
Embedder: emb,
})
if err != nil { ... }
defer closer.Close()
res, err := svc.Write(ctx, memmy.WriteRequest{
Tenant: map[string]string{"user": "alice"},
Message: "the quick brown fox",
})
The schema is bundled in the binary via embed.FS but is NOT applied automatically — operators must call memmy.Migrate() (or the binary's `memmy migrate` subcommand) once before Open. Open refuses to start against a database whose schema version doesn't match what this library was built for.
Index ¶
- Constants
- func Migrate(ctx context.Context, opts MigrationOptions) error
- type Clock
- type DemoteRequest
- type DemoteResult
- type EdgeKind
- type EmbedTask
- type Embedder
- type ErrTenantInvalid
- type FakeClock
- type ForgetRequest
- type ForgetResult
- type GeminiEmbedderOptions
- type MarkRequest
- type MarkResult
- type MigrationOptions
- type Neo4jOptions
- type Options
- type RealClock
- type RecallHit
- type RecallRequest
- type RecallResult
- type ReinforceRequest
- type ReinforceResult
- type ScoreBreakdown
- type Service
- type ServiceConfig
- type StatsRequest
- type StatsResult
- type TenantKeyConfig
- type TenantSchema
- type TenantSchemaConfig
- type WriteRequest
- type WriteResult
Constants ¶
const ( EdgeStructural = types.EdgeStructural EdgeCoRetrieval = types.EdgeCoRetrieval EdgeCoTraversal = types.EdgeCoTraversal )
EdgeKind values. See DESIGN.md §4.3.
const ( EmbedTaskUnspecified = embed.EmbedTaskUnspecified EmbedTaskRetrievalDocument = embed.EmbedTaskRetrievalDocument EmbedTaskRetrievalQuery = embed.EmbedTaskRetrievalQuery EmbedTaskSemanticSimilarity = embed.EmbedTaskSemanticSimilarity EmbedTaskClassification = embed.EmbedTaskClassification EmbedTaskClustering = embed.EmbedTaskClustering EmbedTaskCodeRetrievalQuery = embed.EmbedTaskCodeRetrievalQuery EmbedTaskQuestionAnswering = embed.EmbedTaskQuestionAnswering EmbedTaskFactVerification = embed.EmbedTaskFactVerification )
EmbedTask constants.
Variables ¶
This section is empty.
Functions ¶
func Migrate ¶ added in v0.2.0
func Migrate(ctx context.Context, opts MigrationOptions) error
Migrate applies every embedded migration whose version is greater than the database's current applied version. Idempotent: re-running against an up-to-date database is a no-op.
opts.Dim sets the dimensionality the native vector index is created with on first migration; subsequent calls with a different dim are silently fine because the index is only created once. Callers that later switch embedder dims must drop the existing index manually (see DESIGN.md §13.1) and re-Migrate to re-create it.
Types ¶
type Clock ¶
Clock abstracts time so tests can advance it deterministically. Real{} is the production wall-clock implementation; tests should pass a *FakeClock from NewFakeClock.
type DemoteRequest ¶
type DemoteRequest = types.DemoteRequest
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type DemoteResult ¶
type DemoteResult = types.DemoteResult
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type EdgeKind ¶
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type EmbedTask ¶
EmbedTask classifies how the embedded text will be used. memmy itself only emits RetrievalDocument (Write) and RetrievalQuery (Recall); the other values are reserved for callers passing their own embedder.
type Embedder ¶
Embedder is the pluggable embedding-provider interface. Construct one with NewFakeEmbedder / NewGeminiEmbedder, or supply a custom implementation that conforms to the Embed/Dim contract.
func NewFakeEmbedder ¶
NewFakeEmbedder returns a deterministic test embedder of the given dimensionality. Equal inputs always produce equal vectors. Use in tests; do not use in production.
func NewGeminiEmbedder ¶
func NewGeminiEmbedder(ctx context.Context, opts GeminiEmbedderOptions) (Embedder, error)
NewGeminiEmbedder constructs a Gemini-backed Embedder. It dials the Gemini API immediately to validate credentials.
type ErrTenantInvalid ¶
type ErrTenantInvalid = service.ErrTenantInvalid
ErrTenantInvalid is the typed error returned when a tuple is rejected by the configured TenantSchema. Callers can errors.As() it to surface a corrective payload back to the originating client.
type FakeClock ¶
FakeClock is a controllable Clock for tests.
func NewFakeClock ¶
NewFakeClock returns a *FakeClock initialized to t.
type ForgetRequest ¶
type ForgetRequest = types.ForgetRequest
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type ForgetResult ¶
type ForgetResult = types.ForgetResult
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type GeminiEmbedderOptions ¶
GeminiEmbedderOptions configures NewGeminiEmbedder.
type MarkRequest ¶
type MarkRequest = types.MarkRequest
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type MarkResult ¶
type MarkResult = types.MarkResult
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type MigrationOptions ¶ added in v0.2.0
type MigrationOptions struct {
Neo4j Neo4jOptions
Dim int
}
MigrationOptions configures Migrate. Neo4j configures the backend the migrations are applied to; Dim is the dimensionality the native vector index is created with on first migration.
type Neo4jOptions ¶ added in v0.2.0
type Neo4jOptions struct {
// URI is the bolt:// (or neo4j+s://) address of the Neo4j
// instance. Required.
URI string
// User / Password are the credentials for URI. Required.
User string
Password string
// Database selects the database within the Neo4j instance.
// Optional; "neo4j" by default.
Database string
// ConnectTimeout caps the initial connectivity verification.
// Optional; 10s by default.
ConnectTimeout time.Duration
}
Neo4jOptions bundles the Neo4j backend credentials. The URI, User, and Password are required; everything else has a sensible default. The struct is shared between memmy.Open (Options.Neo4j) and memmy.Migrate (MigrationOptions.Neo4j) so callers configure the backend in one place regardless of which entry point they invoke.
type Options ¶
type Options struct {
// Neo4j configures the storage backend. URI, User, and Password
// are required.
Neo4j Neo4jOptions
// Embedder produces vectors for Write inputs and Recall queries.
// Construct via NewFakeEmbedder or NewGeminiEmbedder, or supply
// your own implementation. Required.
Embedder Embedder
// Clock is the time source for decay and reinforcement math.
// Optional; nil means RealClock{}.
Clock Clock
// ServiceConfig overrides chunking / retrieval / decay / reinforcement
// tunables. nil → use DefaultServiceConfig(). Non-nil is treated as
// the complete config — no field-by-field merging is performed (see
// the ServiceConfig type doc for why). To override a subset:
//
// cfg := memmy.DefaultServiceConfig()
// cfg.NodeDelta = 2.0
// opts.ServiceConfig = &cfg
ServiceConfig *ServiceConfig
// TenantSchema validates tenant tuples on every operation. Optional;
// nil accepts any tuple shape (today's daemon default).
TenantSchema *TenantSchema
// FlatScanThreshold is the per-tenant size below which Recall uses a
// linear scan instead of the native vector index. Optional; 0 → 5000
// (DESIGN.md §6.1).
FlatScanThreshold int
// SkipMigrationCheck disables the schema-version guard at Open.
// Tests-only — production callers should never set this. The
// neo4jtest helper sets it because it manages migrations itself.
SkipMigrationCheck bool
}
Options configures Open. Neo4j and Embedder are required; everything else has a sensible zero-value default.
type RecallHit ¶
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type RecallRequest ¶
type RecallRequest = types.RecallRequest
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type RecallResult ¶
type RecallResult = types.RecallResult
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type ReinforceRequest ¶
type ReinforceRequest = types.ReinforceRequest
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type ReinforceResult ¶
type ReinforceResult = types.ReinforceResult
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type ScoreBreakdown ¶
type ScoreBreakdown = types.ScoreBreakdown
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type Service ¶
type Service = service.MemoryService
Service is the transport-neutral memory API (DESIGN.md §9.1). All operations take a tenant tuple; the underlying TenantID is derived deterministically from the (validated) tuple.
func Open ¶
Open constructs a Service backed by Neo4j at opts.Neo4j.URI. The returned io.Closer must be invoked at shutdown to release the bolt driver connection pool. The Embedder's lifecycle is the caller's responsibility — Open does NOT close it.
Open does not start any transport (MCP / gRPC / HTTP); callers drive the returned Service directly. To run a transport, use the cmd/memmy binary with a YAML config instead.
Open refuses to start against a database whose schema version does not match what this build of memmy expects. The fix is to run memmy.Migrate (or the binary's `memmy migrate` subcommand) once.
type ServiceConfig ¶
ServiceConfig bundles the runtime tunables for chunking, retrieval, decay, reinforcement, and pruning. See DESIGN.md §12.
Options.ServiceConfig is a *ServiceConfig: nil means "use DefaultServiceConfig()", non-nil means "use exactly this struct." To override a subset of fields, start from DefaultServiceConfig() and mutate the returned struct before taking its address. The facade deliberately does NOT do field-by-field merging because some fields (RefractoryPeriod, LogDampening) accept zero as an intentional "disable" signal that a merge-on-zero rule would silently override.
func DefaultServiceConfig ¶
func DefaultServiceConfig() ServiceConfig
DefaultServiceConfig returns the documented service-tunable defaults.
type StatsRequest ¶
type StatsRequest = types.StatsRequest
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type StatsResult ¶
type StatsResult = types.StatsResult
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type TenantKeyConfig ¶
type TenantKeyConfig = config.TenantKeyConfig
TenantKeyConfig is one declared key in a TenantSchemaConfig.
type TenantSchema ¶
type TenantSchema = service.TenantSchema
TenantSchema validates incoming tenant tuples. Construct one via NewTenantSchema, or pass nil to Options.TenantSchema to accept any tuple shape.
func NewTenantSchema ¶
func NewTenantSchema(cfg TenantSchemaConfig) (*TenantSchema, error)
NewTenantSchema compiles a TenantSchema from a config-shaped value. Returns (nil, nil) when cfg has no rules — the caller can pass that nil straight into Options.TenantSchema to mean "accept any tuple."
type TenantSchemaConfig ¶
type TenantSchemaConfig = config.TenantSchemaConfig
TenantSchemaConfig describes the shape of a valid tenant tuple in the same shape the daemon accepts via YAML. Library callers usually construct it programmatically:
cfg := memmy.TenantSchemaConfig{
Description: "single-user agent",
Keys: map[string]memmy.TenantKeyConfig{
"user": {Required: true, Pattern: `^[a-zA-Z0-9_.-]+$`},
"scope": {Enum: []string{"chat", "code"}},
},
}
type WriteRequest ¶
type WriteRequest = types.WriteRequest
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
type WriteResult ¶
type WriteResult = types.WriteResult
Request and result value types — direct re-exports of the wire-neutral shapes defined in internal/types.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
memmy
command
Command memmy runs the memmy LLM-memory MCP server, plus the `migrate` subcommand that applies the bundled Neo4j schema.
|
Command memmy runs the memmy LLM-memory MCP server, plus the `migrate` subcommand that applies the bundled Neo4j schema. |
|
memmy-eval
command
Command memmy-eval is the validation harness CLI for memmy.
|
Command memmy-eval is the validation harness CLI for memmy. |
|
internal
|
|
|
chunker
Package chunker splits a message into sentence-sliding-window chunks.
|
Package chunker splits a message into sentence-sliding-window chunks. |
|
clock
Package clock provides a time abstraction so business logic can be tested deterministically.
|
Package clock provides a time abstraction so business logic can be tested deterministically. |
|
config
Package config loads memmy's YAML configuration.
|
Package config loads memmy's YAML configuration. |
|
embed
Package embed defines the Embedder interface and concrete implementations in subpackages.
|
Package embed defines the Embedder interface and concrete implementations in subpackages. |
|
embed/fake
Package fake provides a deterministic Embedder for tests.
|
Package fake provides a deterministic Embedder for tests. |
|
embed/gemini
Package gemini implements the Embedder interface against Google's Gemini embeddings API via go-genai (google.golang.org/genai).
|
Package gemini implements the Embedder interface against Google's Gemini embeddings API via go-genai (google.golang.org/genai). |
|
eval/corpus
Package corpus extracts plain-text turns from Claude Code session transcripts (`~/.claude/projects/<project>/<sessionUUID>.jsonl`).
|
Package corpus extracts plain-text turns from Claude Code session transcripts (`~/.claude/projects/<project>/<sessionUUID>.jsonl`). |
|
eval/dataset
Package dataset owns the on-disk layout for memmy-eval datasets.
|
Package dataset owns the on-disk layout for memmy-eval datasets. |
|
eval/embedcache
Package embedcache caches embedding vectors keyed by (model_id, dim, sha256(text)) so repeated ingest runs over the same corpus do not re-embed unchanged chunks.
|
Package embedcache caches embedding vectors keyed by (model_id, dim, sha256(text)) so repeated ingest runs over the same corpus do not re-embed unchanged chunks. |
|
eval/harness
Package harness is the composition layer that turns a Claude Code session directory into a memmy store, runs query batteries against it, and captures the per-node state changes that result.
|
Package harness is the composition layer that turns a Claude Code session directory into a memmy store, runs query batteries against it, and captures the per-node state changes that result. |
|
eval/inspect
Package inspect is a read-only window into a memmy Neo4j database used by the eval harness to capture per-node state (weight, last touch, edge degree) before and after a query.
|
Package inspect is a read-only window into a memmy Neo4j database used by the eval harness to capture per-node state (weight, last touch, edge degree) before and after a query. |
|
eval/manifest
Package manifest defines the on-disk metadata records that document what produced an eval dataset and what an eval run actually exercised.
|
Package manifest defines the on-disk metadata records that document what produced an eval dataset and what an eval run actually exercised. |
|
eval/metrics
Package metrics computes the IR + dynamics scores the eval harness reports per run.
|
Package metrics computes the IR + dynamics scores the eval harness reports per run. |
|
eval/queries
Package queries owns the labeled-query side of the eval framework.
|
Package queries owns the labeled-query side of the eval framework. |
|
eval/sweep
Package sweep runs an eval harness over a matrix of memmy configs to find a parameter setting that scores best on a labeled query set.
|
Package sweep runs an eval harness over a matrix of memmy configs to find a parameter setting that scores best on a labeled query set. |
|
graph
Package graph defines the Graph port-out interface used by the Memory Service to persist nodes, messages, and Hebbian memory edges.
|
Package graph defines the Graph port-out interface used by the Memory Service to persist nodes, messages, and Hebbian memory edges. |
|
service
Package service implements the MemoryService — the transport-neutral input port (DESIGN.md §9.1).
|
Package service implements the MemoryService — the transport-neutral input port (DESIGN.md §9.1). |
|
storage/neo4j
Package neo4jstore implements the Graph + VectorIndex ports (DESIGN.md §9.2) over a Neo4j database via the Bolt protocol.
|
Package neo4jstore implements the Graph + VectorIndex ports (DESIGN.md §9.2) over a Neo4j database via the Bolt protocol. |
|
storage/neo4j/neo4jtest
Package neo4jtest is the test helper that opens a per-test Storage handle against the developer's local Neo4j and registers a t.Cleanup that DETACH DELETEs every node carrying the test's unique tenant prefix.
|
Package neo4jtest is the test helper that opens a per-test Storage handle against the developer's local Neo4j and registers a t.Cleanup that DETACH DELETEs every node carrying the test's unique tenant prefix. |
|
transport/mcp
Package mcp adapts the MemoryService onto an MCP server using the official github.com/modelcontextprotocol/go-sdk.
|
Package mcp adapts the MemoryService onto an MCP server using the official github.com/modelcontextprotocol/go-sdk. |
|
types
Package types holds the domain entities used throughout memmy.
|
Package types holds the domain entities used throughout memmy. |
|
vectorindex
Package vectorindex defines the VectorIndex port-out interface used by the Memory Service to store vectors and run top-N similarity search.
|
Package vectorindex defines the VectorIndex port-out interface used by the Memory Service to store vectors and run top-N similarity search. |