memory

package
v2.13.0 Latest Latest
Warning

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

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

Documentation

Overview

Package memory defines interfaces and types for agentic memory — cross-session knowledge that persists beyond a single conversation.

PromptKit defines interfaces and an in-memory test store. Production implementations (vector search, graph retrieval, compliance) are provided by platform layers like Omnia.

Index

Constants

View Source
const (
	RecallToolName   = "memory__recall"
	RememberToolName = "memory__remember"
	ListToolName     = "memory__list"
	ForgetToolName   = "memory__forget"
)

Tool names in the memory namespace.

View Source
const CategoryRubric = `` /* 551-byte string literal not displayed */

CategoryRubric is a prompt fragment that consumer extractors splice into their extraction prompt so the extracting LLM tags each memory with one of the canonical categories. PromptKit owns the rubric so all consumers see the same vocabulary and downstream platforms can apply uniform rules.

Usage:

prompt := basePrompt + "\n" + memory.CategoryRubric
View Source
const ExecutorMode = "memory"

ExecutorMode is the executor name for Mode-based routing.

Variables

This section is empty.

Functions

func DefaultContextFormatter

func DefaultContextFormatter(memories []*Memory) string

DefaultContextFormatter is the formatter the retrieval stage uses when no override is supplied. It renders each memory on its own line as "[type] content (confidence: N.N)" — matching the historical hardcoded behavior. Callers should treat the output as opaque text suitable for direct injection into a system prompt.

func IsKnownCategory

func IsKnownCategory(s string) bool

IsKnownCategory reports whether s exactly matches one of the canonical category strings. Unknown values are not rejected by the storage layer — this helper exists for consumer validation only.

func RegisterMemoryTools

func RegisterMemoryTools(registry *tools.Registry)

RegisterMemoryTools registers the four base memory tools with executor routing.

func ScopeFromContext added in v2.3.0

func ScopeFromContext(ctx context.Context) map[string]string

ScopeFromContext returns the scope attached by WithScope, or nil when the context carries none.

func WithScope added in v2.3.0

func WithScope(ctx context.Context, scope map[string]string) context.Context

WithScope attaches a conversation's memory scope to the context. The Executor reads it on each Execute and reads and writes memories under it, falling back to the scope it was constructed with when absent.

This is what lets a single memory executor, registered once into a shared tools.Registry, serve concurrent conversations without their memories crossing. A Registry keeps exactly one executor per name, so if the scope were captured at construction, the last conversation to register would own the memory tool for every conversation in flight -- one conversation's remember would land in another's scope and be invisible in its own. It mirrors tools.WithMCPRegistry, which exists for the same reason.

An empty scope is ignored: installing one would silently widen or narrow every read rather than doing nothing.

Types

type ConsentCategory

type ConsentCategory string

ConsentCategory is the well-known taxonomy used by consent-aware consumers (e.g. Omnia) to apply per-category retention, opt-outs, and PII rules at memory-write time. Values are stored in Memory.Metadata under the key MetaKeyConsentCategory regardless of which path produced the memory: the explicit `memory__remember` tool (LLM-supplied category arg) or an extractor stage that classifies and tags during write.

PromptKit defines the vocabulary and helpers; semantics (retention, access control, redaction) are owned by the consumer.

const (
	CategoryIdentity    ConsentCategory = "memory:identity"    // Names, IDs, pronouns, contact details.
	CategoryPreferences ConsentCategory = "memory:preferences" // Likes, dislikes, settings, configuration.
	CategoryContext     ConsentCategory = "memory:context"     // Work / project context, domain knowledge, current task.
	CategoryLocation    ConsentCategory = "memory:location"    // Geographic info, addresses, IP.
	CategoryHealth      ConsentCategory = "memory:health"      // Health, dietary, medical, accessibility info.
	CategoryHistory     ConsentCategory = "memory:history"     // Past conversations, decisions, what was said before.
)

Known consent categories. The string values are the wire format consumers match against — do not change them without coordinating with downstream platforms.

func KnownCategories

func KnownCategories() []ConsentCategory

KnownCategories returns the canonical set of categories in a stable order. Useful for filling option lists, validation tables, or rubric expansion.

type ContextFormatter

type ContextFormatter func(memories []*Memory) string

ContextFormatter renders a slice of retrieved memories into the string that gets written onto TurnState.Variables["memory_context"] by the retrieval pipeline stage. Hosts implement this to control how categories, dedup keys, confidence, or other metadata are surfaced to the LLM. See DefaultContextFormatter for the built-in behavior.

type DeleteOptions

type DeleteOptions struct {
	// Extras carries top-level forget args the executor does not type.
	// See [RetrieveOptions.Extras].
	Extras map[string]any
}

DeleteOptions configures a memory delete. It exists only to carry Extras: Store.Delete has no options parameter, so a store that wants the passthrough args implements ExtrasDeleter instead.

type Executor

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

Executor implements tools.Executor for all memory tools. It routes by tool name to the appropriate Store method.

The scope it was constructed with is a default, not a binding: every call prefers the scope on the context (see WithScope). One Executor is all a tools.Registry holds per name, so a host running concurrent conversations over a shared registry must scope per call or their memories cross.

func NewExecutor

func NewExecutor(store Store, scope map[string]string) *Executor

NewExecutor creates a Executor for the given store and default scope.

func (*Executor) Execute

func (e *Executor) Execute(
	ctx context.Context, desc *tools.ToolDescriptor, args json.RawMessage,
) (json.RawMessage, error)

Execute implements tools.Executor. Routes by tool name.

func (*Executor) Name

func (e *Executor) Name() string

Name implements tools.Executor.

type Extractor

type Extractor interface {
	Extract(ctx context.Context, scope map[string]string, messages []types.Message) ([]*Memory, error)
}

Extractor derives memories from conversation messages. PromptKit defines the interface only. Implementations are provided by platform layers (Omnia) or SDK examples.

type ExtrasDeleter

type ExtrasDeleter interface {
	DeleteWithOptions(
		ctx context.Context, scope map[string]string, memoryID string, opts DeleteOptions,
	) error
}

ExtrasDeleter is optionally implemented by stores that accept backend-specific arguments on delete.

Store.Delete takes no options struct, so it has nowhere to carry the passthrough args a host adds to memory__forget's input schema with sdk.WithToolDescriptorOverride. Rather than change Delete's signature (which every Store implementation would have to follow), a store opts in by implementing this. The memory executor prefers it when present and falls back to Delete otherwise, so a store that ignores it is unaffected.

Recall and list need no equivalent: RetrieveOptions and ListOptions are parameters, so Extras is a field on each of them.

type InMemoryStore

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

InMemoryStore is a test/development memory store. Substring matching for retrieval, no vector search. Not for production use.

func NewInMemoryStore

func NewInMemoryStore() *InMemoryStore

NewInMemoryStore creates a new in-memory store.

func (*InMemoryStore) Delete

func (s *InMemoryStore) Delete(_ context.Context, scope map[string]string, memoryID string) error

Delete removes a specific memory by ID.

func (*InMemoryStore) DeleteAll

func (s *InMemoryStore) DeleteAll(_ context.Context, scope map[string]string) error

DeleteAll removes all memories for a scope.

func (*InMemoryStore) List

func (s *InMemoryStore) List(
	_ context.Context, scope map[string]string, opts ListOptions,
) ([]*Memory, error)

List returns memories matching the scope and filters.

func (*InMemoryStore) Retrieve

func (s *InMemoryStore) Retrieve(
	_ context.Context, scope map[string]string, query string, opts RetrieveOptions,
) ([]*Memory, error)

Retrieve searches memories by substring matching on content.

func (*InMemoryStore) Save

func (s *InMemoryStore) Save(_ context.Context, m *Memory) error

Save stores a memory. Generates an ID if empty.

type ListOptions

type ListOptions struct {
	Types  []string
	Limit  int
	Offset int
	// Extras carries top-level list args the executor does not type.
	// See [RetrieveOptions.Extras].
	Extras map[string]any
}

ListOptions configures a memory list query.

type Memory

type Memory struct {
	ID         string            `json:"id"`
	Type       string            `json:"type"`               // Free-form: "preference", "episodic", "code_symbol", etc.
	Content    string            `json:"content"`            // Natural language summary
	Metadata   map[string]any    `json:"metadata,omitempty"` // Structured data, store-specific extensions
	Confidence float64           `json:"confidence"`         // 0.0-1.0
	Scope      map[string]string `json:"scope"`              // Scoping keys: {"user_id": "x", "workspace_id": "y"}
	SessionID  string            `json:"session_id,omitempty"`
	TurnRange  [2]int            `json:"turn_range,omitempty"`
	CreatedAt  time.Time         `json:"created_at"`
	AccessedAt time.Time         `json:"accessed_at"`
	ExpiresAt  *time.Time        `json:"expires_at,omitempty"`
}

Memory represents a single memory unit. It is thin: domain-specific concerns (purpose, trust model, sensitivity) belong in the store implementation, not the type.

func (*Memory) GetConsentCategory

func (m *Memory) GetConsentCategory() ConsentCategory

GetConsentCategory returns the consent category written via Memory.SetConsentCategory or the `memory__remember` tool, or empty string when unset.

func (*Memory) GetProvenance

func (m *Memory) GetProvenance() Provenance

GetProvenance returns the provenance from metadata, or empty string if unset.

func (*Memory) SetConsentCategory

func (m *Memory) SetConsentCategory(c ConsentCategory)

SetConsentCategory writes a category onto m.Metadata[MetaKeyConsentCategory], initializing the map when nil. Empty input is a no-op so callers can pass LLM output unconditionally without checking first. Unknown (non-canonical) values are accepted as-is — see IsKnownCategory for validation.

func (*Memory) SetProvenance

func (m *Memory) SetProvenance(p Provenance)

SetProvenance sets the provenance metadata on a Memory, initializing the Metadata map if nil. This always overwrites any existing provenance value to prevent callers from spoofing provenance.

type Provenance

type Provenance string

Provenance indicates how a memory was created. Downstream systems (PII redaction, audit, retention) use this to apply context-appropriate policies. Stored in Memory.Metadata[MetaKeyProvenance].

const (
	// MetaKeyProvenance is the well-known Metadata key for provenance.
	MetaKeyProvenance = "provenance"

	// MetaKeyConsentCategory is the well-known Metadata key for the
	// consent category attached to a memory. Two write paths populate it:
	//
	//   - Explicit: the LLM calls memory__remember with a category arg,
	//     which the executor stashes here verbatim.
	//   - Implicit: an Extractor stage classifies and tags during write,
	//     typically via [Memory.SetConsentCategory] driven by the
	//     extracting LLM's structured output ([CategoryRubric] supplies
	//     the prompt fragment).
	//
	// Consumers that classify server-side may fall back to their own
	// classifier when this is absent. Values are not validated by
	// PromptKit — see [IsKnownCategory] for an opt-in check against the
	// canonical [ConsentCategory] taxonomy.
	MetaKeyConsentCategory = "consent_category"

	// ProvenanceUserRequested — user explicitly asked the agent to remember this.
	ProvenanceUserRequested Provenance = "user_requested"

	// ProvenanceAgentExtracted — the agent/pipeline extracted this from
	// conversation without an explicit user request (safe default).
	ProvenanceAgentExtracted Provenance = "agent_extracted"

	// ProvenanceSystemGenerated — created by system logic, not from user content.
	ProvenanceSystemGenerated Provenance = "system_generated"

	// ProvenanceOperatorCurated — manually created/edited by an operator.
	ProvenanceOperatorCurated Provenance = "operator_curated"
)

type RetrieveOptions

type RetrieveOptions struct {
	Types         []string // Filter by memory type (empty = all)
	Limit         int      // Max results (0 = store default)
	MinConfidence float64  // Minimum confidence threshold (0 = no filter)
	// Extras carries top-level recall args the executor does not type,
	// so a store can accept backend-specific parameters without forking
	// PromptKit. Hosts extend memory__recall's InputSchema with
	// sdk.WithToolDescriptorOverride and read the values here; a store
	// that does not recognize a key ignores it. Nil when the call carried
	// no untyped args. This mirrors what Memory.Metadata does on the
	// write side. See AltairaLabs/PromptKit#1987.
	Extras map[string]any
}

RetrieveOptions configures a memory retrieval query.

type Retriever

type Retriever interface {
	RetrieveContext(ctx context.Context, scope map[string]string, messages []types.Message) ([]*Memory, error)
}

Retriever finds relevant memories given conversation context. Used by the retrieval pipeline stage for automatic RAG injection. Different from Store.Retrieve() which is tool-facing (specific query). Retriever sees the full conversation context and decides what's relevant.

type Store

type Store interface {
	Save(ctx context.Context, memory *Memory) error
	Retrieve(ctx context.Context, scope map[string]string, query string, opts RetrieveOptions) ([]*Memory, error)
	List(ctx context.Context, scope map[string]string, opts ListOptions) ([]*Memory, error)
	Delete(ctx context.Context, scope map[string]string, memoryID string) error
	DeleteAll(ctx context.Context, scope map[string]string) error
}

Store is the core memory persistence interface.

type ToolProvider

type ToolProvider interface {
	RegisterTools(registry *tools.Registry)
}

ToolProvider is optionally implemented by stores that want to register additional tools beyond the base recall/remember/list/forget. Custom tools are registered in the "memory" namespace.

Directories

Path Synopsis
Package corpus provides a reference memory.Retriever over a fixed set of documents — a knowledge base the host supplies, separate from the memory.Store the memory tools read and write.
Package corpus provides a reference memory.Retriever over a fixed set of documents — a knowledge base the host supplies, separate from the memory.Store the memory tools read and write.

Jump to

Keyboard shortcuts

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