service

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 30, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package service implements the MemoryService — the transport-neutral input port (DESIGN.md §9.1). It composes the Embedder, VectorIndex, and Graph ports to deliver Write / Recall / Forget / Stats operations with lazy decay, Hebbian reinforcement, and weight-aware retrieval.

The service is stateless across calls (DESIGN.md §0 #3): no caches, no in-memory accumulators. All state lives in the database.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Chunking
	ChunkWindowSize int
	ChunkStride     int

	// Retrieval defaults
	DefaultK           int
	DefaultHops        int
	DefaultOversample  int
	SimAlpha           float64
	WeightBeta         float64
	DepthPenaltyFactor float64 // multiplier per hop, default 2.0 → /2 per depth

	// Decay (per-second)
	NodeLambda            float64
	EdgeStructuralLambda  float64
	EdgeCoRetrievalLambda float64
	EdgeCoTraversalLambda float64

	// Reinforcement
	NodeDelta                    float64
	EdgeCoRetrievalBase          float64
	EdgeCoTraversalMultiplier    float64
	EdgeStructuralWeight         float64
	EdgeStructuralTemporalWeight float64

	// Pruning
	EdgeFloor float64
	NodeFloor float64
	WeightCap float64

	// Structural temporal recency
	StructuralRecentN     int
	StructuralRecentDelta time.Duration

	// Explicit-bump throttling (Reinforce/Demote/Mark only).
	// RefractoryPeriod blocks repeated explicit bumps on the same node
	// within the window — the call still updates LastTouched and
	// AccessCount but applies no delta. Implicit Recall co-retrieval
	// bumps are NOT refractory-gated. Set to 0 to disable.
	RefractoryPeriod time.Duration

	// LogDampening makes positive bumps approach WeightCap asymptotically
	// instead of hitting a hard wall: effective_delta = delta * (1 - w/cap).
	// Demote (negative delta) is unaffected. Implicit Recall co-retrieval
	// bumps are NOT log-dampened.
	LogDampening bool

	// MarkMaxNodes caps the number of recent nodes Mark walks per call.
	MarkMaxNodes int
}

Config bundles the tunables for chunking, retrieval, decay, and reinforcement. See DESIGN.md §12.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns the documented defaults from DESIGN.md §12.

type ErrTenantInvalid

type ErrTenantInvalid struct {
	Code    string // tenant_unknown_key | tenant_enum_mismatch | ...
	Field   string // empty when the error isn't field-specific
	Got     string // the offending value (when applicable)
	Message string
}

ErrTenantInvalid is the typed error returned when a tuple is rejected. It carries enough structured detail that MCP handlers can surface a corrective payload back to the LLM.

func (*ErrTenantInvalid) Error

func (e *ErrTenantInvalid) Error() string

func (*ErrTenantInvalid) Payload

func (e *ErrTenantInvalid) Payload(expected *jsonschema.Schema) ([]byte, error)

Payload returns a JSON-serializable detail object suitable for inclusion in an MCP CallToolResult error payload alongside the expected JSON Schema.

type MemoryService

MemoryService is the transport-neutral application port. All transport adapters (MCP, gRPC, HTTP) call into this interface.

type Service

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

Service is the concrete MemoryService implementation.

func New

New constructs a Service. All four ports are required. The schema is optional — pass nil to accept any tenant tuple (today's behavior).

func (*Service) Demote

Demote applies an explicit caller-driven inhibition to a single node. Used to record "this hit was misleading or wrong."

Bump magnitude is -NodeDelta. The post-update weight is clamped at NodeFloor — Demote never deletes the node. The same refractory window applies (a single retrieval can't be repeatedly demoted within the window). Demote bypasses LogDampening so its effect is not damped near WeightCap. See DESIGN.md §8.2.

func (*Service) Forget

Forget removes either a single message (and all derived nodes/vectors/ HNSW records/edges) by ID, or all messages created strictly before a given timestamp.

func (*Service) Mark

Mark retroactively boosts every node in the tenant whose CreatedAt falls within [Since, now]. Per-node delta is `Strength * NodeDelta`, scaled linearly by recency: most recently created nodes within the window get the full bump; nodes near the edge of the window get a fractional bump.

Each per-node application goes through the same refractory and log-dampening path as Reinforce.

See DESIGN.md §8.2 (synaptic-tag capture analog).

func (*Service) Recall

Recall implements the full retrieval pipeline (DESIGN.md §6).

Phases:

  1. Embed query, normalize.
  2. Vector search with oversample.
  3. For each candidate: lazy-decay-then-reinforce node weight.
  4. Re-rank by sim^α × weight^β; take top-K → seeds.
  5. Hebbian co-retrieval: reinforce edges between every seed pair.
  6. BFS expansion via memory edges, with edge-floor pruning + depth penalty.
  7. Co-traversal reinforcement on edges that delivered nodes into the final returned result set.
  8. Build provenance hits with score breakdowns + path.

func (*Service) Reinforce

Reinforce applies an explicit caller-driven LTP bump to a single node. Used to record "this hit was useful in my answer."

Bump magnitude is the configured NodeDelta. Repeated bumps approach WeightCap asymptotically (LogDampening). A per-node refractory window (RefractoryPeriod) prevents double-counting when a single retrieval is reinforced multiple times in quick succession; the call still updates LastTouched and AccessCount so the system knows the access happened. See DESIGN.md §8.2.

func (*Service) Schema

func (s *Service) Schema() *TenantSchema

Schema returns the active TenantSchema, or nil if none is configured. Used by transport adapters to render the schema into wire-level input schemas and to surface corrective errors back to clients.

func (*Service) Stats

Stats aggregates counts for one tenant or all tenants.

func (*Service) Write

Write ingests a message: chunk it, embed each chunk, persist nodes + vectors + HNSW records, and create structural memory edges.

Order matters:

  1. Embed BEFORE any storage write (DESIGN.md §5).
  2. Persist message + nodes + vectors + HNSW.
  3. Create structural edges (sequential within message + recent within tenant).

type TenantKey

type TenantKey struct {
	Description string
	Pattern     *regexp.Regexp // nil if no pattern
	PatternRaw  string
	Enum        []string
	Required    bool
}

TenantKey is one declared tuple key.

type TenantSchema

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

TenantSchema validates a tenant tuple against a configured shape and renders the equivalent JSON Schema for MCP InputSchema patching.

The schema only validates incoming tuples — it does NOT transform them. TenantID is derived from the validated tuple as today (see DESIGN.md §3). Stored memories are not migrated when the schema changes; data written under one schema remains addressable if the schema is later changed back to one that accepts the original tuple shape.

func NewTenantSchemaFromConfig

func NewTenantSchemaFromConfig(cfg config.TenantSchemaConfig) (*TenantSchema, error)

NewTenantSchemaFromConfig compiles a TenantSchema from config. Returns (nil, nil) when no schema is configured — callers treat nil as "accept any tuple."

func (*TenantSchema) Description

func (s *TenantSchema) Description() string

Description returns the top-level description string for use in the rendered JSON Schema and in MCP tool descriptions.

func (*TenantSchema) JSONSchema

func (s *TenantSchema) JSONSchema() *jsonschema.Schema

JSONSchema renders the schema as a *jsonschema.Schema suitable for patching into an MCP tool's InputSchema (the `tenant` property).

func (*TenantSchema) Validate

func (s *TenantSchema) Validate(tuple map[string]string) error

Validate enforces the schema against a tuple. Returns *ErrTenantInvalid when the tuple is rejected. nil-receiver = accept anything.

type TenantStats

type TenantStats struct {
	NodeCount     int
	EdgeCount     int
	HNSWSize      int
	SumNodeWeight float64
	SumEdgeWeight float64
}

TenantStats is the per-tenant breakdown returned by a backend implementing statsScanner.

Jump to

Keyboard shortcuts

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